From 98583c42560a082c9d9898ba9e35cbd68ad15815 Mon Sep 17 00:00:00 2001 From: Frederic Lecaille Date: Mon, 15 Apr 2024 09:57:37 +0200 Subject: [PATCH] BUG/MEDIUM: grpc: Fix several unaligned 32/64 bits accesses There were several places in grpc and its dependency protobuf where unaligned accesses were done. Read accesses to 32 (resp. 64) bits values should be performed by read_u32() (resp. read_u64()). Replace these unligned read accesses by correct calls to these functions. Same fixes for doubles and floats. Such unaligned read accesses could lead to crashes with bus errors on CPU archictectures which do not fix them at run time. This patch depends on this previous commit: 861199fa71 MINOR: net_helper: Add support for floats/doubles. Must be backported as far as 2.6. --- include/haproxy/protobuf.h | 10 +++++----- src/sample.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/haproxy/protobuf.h b/include/haproxy/protobuf.h index 009bd13d7..512288b5e 100644 --- a/include/haproxy/protobuf.h +++ b/include/haproxy/protobuf.h @@ -365,13 +365,13 @@ int protobuf_smp_store_64bit(struct sample *smp, int type, case PBUF_T_64BIT_FIXED64: case PBUF_T_64BIT_SFIXED64: smp->data.type = SMP_T_SINT; - smp->data.u.sint = pbuf_le64toh(*(uint64_t *)pos); + smp->data.u.sint = pbuf_le64toh(read_u64(pos)); smp->flags = SMP_F_VOL_TEST; break; case PBUF_T_64BIT_DOUBLE: smp->data.type = SMP_T_SINT; - smp->data.u.sint = pbuf_le64toh(*(double *)pos); + smp->data.u.sint = pbuf_le64toh(read_dbl(pos)); smp->flags = SMP_F_VOL_TEST; break; @@ -455,19 +455,19 @@ int protobuf_smp_store_32bit(struct sample *smp, int type, case PBUF_T_32BIT_FIXED32: smp->data.type = SMP_T_SINT; - smp->data.u.sint = pbuf_le32toh(*(uint32_t *)pos); + smp->data.u.sint = pbuf_le32toh(read_u32(pos)); smp->flags = SMP_F_VOL_TEST; break; case PBUF_T_32BIT_SFIXED32: smp->data.type = SMP_T_SINT; - smp->data.u.sint = (int32_t)pbuf_le32toh(*(uint32_t *)pos); + smp->data.u.sint = (int32_t)pbuf_le32toh(read_u32(pos)); smp->flags = SMP_F_VOL_TEST; break; case PBUF_T_32BIT_FLOAT: smp->data.type = SMP_T_SINT; - smp->data.u.sint = pbuf_le32toh(*(float *)pos); + smp->data.u.sint = pbuf_le32toh(read_flt(pos)); smp->flags = SMP_F_VOL_TEST; break; diff --git a/src/sample.c b/src/sample.c index 8f46d31b9..334782c17 100644 --- a/src/sample.c +++ b/src/sample.c @@ -3818,7 +3818,7 @@ static int sample_conv_ungrpc(const struct arg *arg_p, struct sample *smp, void while (grpc_left > GRPC_MSG_HEADER_SZ) { size_t grpc_msg_len, left; - grpc_msg_len = left = ntohl(*(uint32_t *)(pos + GRPC_MSG_COMPRESS_FLAG_SZ)); + grpc_msg_len = left = ntohl(read_u32(pos + GRPC_MSG_COMPRESS_FLAG_SZ)); pos += GRPC_MSG_HEADER_SZ; grpc_left -= GRPC_MSG_HEADER_SZ;