Commit 42ada5daf9 for qemu.org
commit 42ada5daf959bc60beb4b4335dfbdc9eb8ee9b41
Author: Peter Maydell <peter.maydell@linaro.org>
Date: Thu Feb 12 14:09:15 2026 +0000
net: mark struct eth_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:78:47: runtime error: member access within misaligned address 0x561f52f35011 for type 'struct eth_header', which requires 2 byte alignment
0x561f52f35011: note: pointer points here
00 00 00 00 33 33 00 00 00 16 52 54 00 12 34 56 86 dd 60 00 00 00 00 24 00 01 00 00 00 00 00 00
^
#0 0x561f20608459 in net_checksum_calculate /home/pm215/qemu/build/clang/../../net/checksum.c:78:47
#1 0x561f20117bfa in gem_transmit /home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1386:21
#2 0x561f20115c61 in gem_write /home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1650:13
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../net/checksum.c:78:47
Fix this by marking the eth_header struct as QEMU_PACKED, so that the
compiler knows it might be unaligned and will generate the right code
for accessing fields.
This is similar to commit f8b94b4c520 ("net: mark struct ip_header as
QEMU_PACKED") where we fixed this for a different struct defined in
this file.
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-4-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 14c34f530f..63f598d7cd 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -39,7 +39,7 @@ struct eth_header {
uint8_t h_dest[ETH_ALEN]; /* destination eth addr */
uint8_t h_source[ETH_ALEN]; /* source ether addr */
uint16_t h_proto; /* packet type ID field */
-};
+} QEMU_PACKED;
struct vlan_header {
uint16_t h_tci; /* priority and VLAN ID */