Browse Source

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 f8b94b4c52 ("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>
master
Peter Maydell 2 months ago
committed by Philippe Mathieu-Daudé
parent
commit
42ada5daf9
  1. 2
      include/net/eth.h

2
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 */

Loading…
Cancel
Save