From: Peter Maydell <[email protected]>

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:144:24: runtime error: member access within misaligned 
address 0x619a74c32033 for type 'tcp_header' (aka 'struct tcp_header'), which 
requires 4 byte alignment
0x619a74c32033: note: pointer points here
 0a  00 02 02 86 aa 00 16 52  c1 d3 70 00 00 00 00 a0  02 fa f0 00 00 00 00 02  
04 05 b4 04 02 08 0a
              ^
    #0 0x619a6ba84794 in net_checksum_calculate 
/home/pm215/qemu/build/clang/../../net/checksum.c:144:24
    #1 0x619a6b5940da in gem_transmit 
/home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1386:21
    #2 0x619a6b592141 in gem_write 
/home/pm215/qemu/build/clang/../../hw/net/cadence_gem.c:1650:13

Fix this by marking the tcp_header struct as QEMU_PACKED.

Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Akihiko Odaki <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
 include/net/eth.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/net/eth.h b/include/net/eth.h
index df90ff08374..efe270dbfe7 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -68,7 +68,7 @@ typedef struct tcp_header {
     uint16_t th_win;            /* window */
     uint16_t th_sum;            /* checksum */
     uint16_t th_urp;            /* urgent pointer */
-} tcp_header;
+} QEMU_PACKED tcp_header;
 
 #define TCP_FLAGS_ONLY(flags) ((flags) & 0x3f)
 
-- 
2.52.0


Reply via email to