Commit 2ca81b0eb3 for qemu.org
commit 2ca81b0eb3249f66efba6707cc9d6577830e2329
Author: Peter Maydell <peter.maydell@linaro.org>
Date: Thu Feb 12 14:09:16 2026 +0000
net: mark struct udp_header as QEMU_PACKED
The eth_header is not actually guaranteed to be aligned. We attempt
to deal with this in some places such as net_checksum_calculate() by
using lduw_be_p() and so on to access the fields, but this is not
sufficient to be correct, because even accessing a byte member within
a misaligned struct is undefined behaviour. The clang sanitizer will
emit an error like this if you run the sifive_u_mmc functional test
with sanitizers enabled:
../../net/checksum.c:168:24: runtime error: member access within misaligned address 0x5b7a7f829033 for type 'udp_header' (aka 'struct udp_header'), which requires 2 byte alignment
0x5b7a7f829033: note: pointer points here
ff ff ff ff 00 44 00 43 01 34 58 54 01 01 06 00 85 95 80 60 00 00 00 00 00 00 00 00 00 00 00 00
^
#0 0x5b7a71a5887e in net_checksum_calculate /home/pm215/qemu/build/clang/../../net/checksum.c:168:24
#1 0x5b7a7156819a in gem_transmit /home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1386:21
#2 0x5b7a71566201 in gem_write /home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1650:13
Fix this by marking the udp_header struct as QEMU_PACKED,
so that the compiler knows it might be unaligned and will
generate the right code for accessing fields.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Message-ID: <20260212140917.1443253-5-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
diff --git a/include/net/eth.h b/include/net/eth.h
index 63f598d7cd..df90ff0837 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -85,7 +85,7 @@ typedef struct udp_header {
uint16_t uh_dport; /* destination port */
uint16_t uh_ulen; /* udp length */
uint16_t uh_sum; /* udp checksum */
-} udp_header;
+} QEMU_PACKED udp_header;
typedef struct ip_pseudo_header {
uint32_t ip_src;