From 3609630e7910f04a007e48e4520c04fbb942658e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 12 Feb 2026 14:09:14 +0000 Subject: [PATCH] hw/net/rocker: Don't assume h_proto is aligned in eth_strip_vlan_ex() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In eth_strip_vlan_ex() we take a pointer to the eth_header h_proto field into a local uint16_t* variable, and then later in the function we dereference that pointer. This isn't safe, because the eth_header struct may not be aligned, and if we mark the struct as QEMU_PACKED then gcc will complain about taking the address of a field in a packed struct. Instead, make the local variable be a void* and use the appropriate functions for accessing 16 bits of possibly unaligned data through it. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Akihiko Odaki Message-ID: <20260212140917.1443253-3-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- net/eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/eth.c b/net/eth.c index 3f680cc033..12ec316e24 100644 --- a/net/eth.c +++ b/net/eth.c @@ -274,7 +274,7 @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, int index, uint16_t *payload_offset, uint16_t *tci) { struct vlan_header vlan_hdr; - uint16_t *new_ehdr_proto; + void *new_ehdr_proto; size_t new_ehdr_size; size_t copied; @@ -298,7 +298,7 @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, int index, return 0; } - if (copied < new_ehdr_size || be16_to_cpu(*new_ehdr_proto) != vet) { + if (copied < new_ehdr_size || lduw_be_p(new_ehdr_proto) != vet) { return 0; } @@ -308,7 +308,7 @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, int index, return 0; } - *new_ehdr_proto = vlan_hdr.h_proto; + stw_he_p(new_ehdr_proto, vlan_hdr.h_proto); *payload_offset = iovoff + new_ehdr_size + sizeof(vlan_hdr); *tci = be16_to_cpu(vlan_hdr.h_tci);