diff mbox series

[v2,2/2] net: mark struct ip_header as QEMU_PACKED

Message ID 20241114141619.806652-3-peter.maydell@linaro.org (mailing list archive)
State New
Headers show
Series net: Make ip_header struct QEMU_PACKED | expand

Commit Message

Peter Maydell Nov. 14, 2024, 2:16 p.m. UTC
The ip_header is not actually guaranteed to be aligned. We attempt to
deal with this in some places such as net_checksum_calculate() by
using stw_be_p and so on to access the fields, but this is not
sufficient to be correct, because even accessing a byte member
within an unaligned struct is undefined behaviour. The clang
sanitizer will emit warnings like these if net_checksum_calculate()
is called:

     Stopping network: ../../net/checksum.c:106:9: runtime error: member access within misaligned address 0x556aad9b502e for type 'struct ip_header', which requires 4 byte alignment
    0x556aad9b502e: note: pointer points here
     34 56 08 00 45 00  01 48 a5 09 40 00 40 11  7c 8b 0a 00 02 0f 0a 00  02 02 00 44 00 43 01 34  19 56
                 ^
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../net/checksum.c:106:9 in
    ../../net/checksum.c:106:9: runtime error: load of misaligned address 0x556aad9b502e for type 'uint8_t' (aka 'unsigned char'), which requires 4 byte alignment
    0x556aad9b502e: note: pointer points here
     34 56 08 00 45 00  01 48 a5 09 40 00 40 11  7c 8b 0a 00 02 0f 0a 00  02 02 00 44 00 43 01 34  19 56
                 ^

Fix this by marking the ip_header struct as QEMU_PACKED, so that
the compiler knows that it might be unaligned and will generate
the right code for accessing fields.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/net/eth.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Philippe Mathieu-Daudé Nov. 14, 2024, 2:36 p.m. UTC | #1
On 14/11/24 14:16, Peter Maydell wrote:
> The ip_header is not actually guaranteed to be aligned. We attempt to
> deal with this in some places such as net_checksum_calculate() by
> using stw_be_p and so on to access the fields, but this is not
> sufficient to be correct, because even accessing a byte member
> within an unaligned struct is undefined behaviour. The clang
> sanitizer will emit warnings like these if net_checksum_calculate()
> is called:
> 
>       Stopping network: ../../net/checksum.c:106:9: runtime error: member access within misaligned address 0x556aad9b502e for type 'struct ip_header', which requires 4 byte alignment
>      0x556aad9b502e: note: pointer points here
>       34 56 08 00 45 00  01 48 a5 09 40 00 40 11  7c 8b 0a 00 02 0f 0a 00  02 02 00 44 00 43 01 34  19 56
>                   ^
>      SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../net/checksum.c:106:9 in
>      ../../net/checksum.c:106:9: runtime error: load of misaligned address 0x556aad9b502e for type 'uint8_t' (aka 'unsigned char'), which requires 4 byte alignment
>      0x556aad9b502e: note: pointer points here
>       34 56 08 00 45 00  01 48 a5 09 40 00 40 11  7c 8b 0a 00 02 0f 0a 00  02 02 00 44 00 43 01 34  19 56
>                   ^
> 
> Fix this by marking the ip_header struct as QEMU_PACKED, so that
> the compiler knows that it might be unaligned and will generate
> the right code for accessing fields.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   include/net/eth.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Should this series be tagged for qemu-stable@?
diff mbox series

Patch

diff --git a/include/net/eth.h b/include/net/eth.h
index 3b80b6e07f3..14c34f530fe 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -56,7 +56,7 @@  struct ip_header {
     uint8_t  ip_p;           /* protocol */
     uint16_t ip_sum;         /* checksum */
     uint32_t ip_src, ip_dst; /* source and destination address */
-};
+} QEMU_PACKED;
 
 typedef struct tcp_header {
     uint16_t th_sport;          /* source port */