From: Peter Maydell Date: Tue, 5 May 2026 18:51:57 +0000 (+0100) Subject: hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71d027cfee8553e2ec28efa1ddd7fd0ecbadcc86;p=thirdparty%2Fqemu.git hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() _of_dpa_flow_match() tries to do masked comparisons of OfDpaFlowkey structs by casting pointers to them to uint64_t* and then doing the memory accesses as 64-bit. This is undefined behaviour because the pointers might not be 64-bit aligned, and the UB sanitizer spots this: ../../hw/net/rocker/rocker_of_dpa.c:321:20: runtime error: load of misaligned address 0x512000164044 for type 'uint64_t' (aka 'unsigned long'), which requires 8 byte alignment 0x512000164044: note: pointer points here 02 00 00 00 00 00 ff ff 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ We do know that OfDpaFlowKey structs must be at least aligned enough for uint32_t accesses, because that's the type of the first field. Switch to using uint32_t accesses in the loop. Because the "width" field is always set via the FLOW_KEY_WIDTH macro and not exposed to the guest, we can adjust the macro to store the number of uint32_t to be checked rather than needing to change the loop boundary in the match function. Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Signed-off-by: Jason Wang --- diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c index 958f3006c1..3d6f55b512 100644 --- a/hw/net/rocker/rocker_of_dpa.c +++ b/hw/net/rocker/rocker_of_dpa.c @@ -99,13 +99,13 @@ typedef struct of_dpa_flow_key { } nd; } ipv6; }; - int width; /* how many uint64_t's in key? */ + int width; /* how many uint32_t's in key? */ } OfDpaFlowKey; -/* Width of key which includes field 'f' in u64s, rounded up */ +/* Width of key which includes field 'f' in u32s, rounded up */ #define FLOW_KEY_WIDTH(f) \ DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof_field(OfDpaFlowKey, f), \ - sizeof(uint64_t)) + sizeof(uint32_t)) typedef struct of_dpa_flow_action { uint32_t goto_tbl; @@ -304,9 +304,9 @@ static void _of_dpa_flow_match(void *key, void *value, void *user_data) { OfDpaFlow *flow = value; OfDpaFlowMatch *match = user_data; - uint64_t *k = (uint64_t *)&flow->key; - uint64_t *m = (uint64_t *)&flow->mask; - uint64_t *v = (uint64_t *)&match->value; + uint32_t *k = (uint32_t *)&flow->key; + uint32_t *m = (uint32_t *)&flow->mask; + uint32_t *v = (uint32_t *)&match->value; int i; if (flow->key.tbl_id == match->value.tbl_id) {