[PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info

Gustavo A. R. Silva posted 1 patch 1 month ago
drivers/net/virtio_net.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
[PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Gustavo A. R. Silva 1 month ago
Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
along with the following warning:

drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

This helper creates a union between a flexible-array member (FAM)
and a set of members that would otherwise follow it (in this case
`u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
overlays the trailing members (rss_hash_key_data) onto the FAM
(hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
The static_assert() ensures this alignment remains.

Notice that due to tail padding in flexible `struct
virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
(at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
offset 84 in struct virtnet_info) are misaligned by one byte. See
below:

struct virtio_net_rss_config_trailer {
        __le16                     max_tx_vq;            /*     0     2 */
        __u8                       hash_key_length;      /*     2     1 */
        __u8                       hash_key_data[];      /*     3     0 */

        /* size: 4, cachelines: 1, members: 3 */
        /* padding: 1 */
        /* last cacheline: 4 bytes */
};

struct virtnet_info {
...
        struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */

        /* XXX last struct has 1 byte of padding */

        u8                         rss_hash_key_data[40]; /*    84    40 */
...
        /* size: 832, cachelines: 13, members: 48 */
        /* sum members: 801, holes: 8, sum holes: 31 */
        /* paddings: 2, sum paddings: 5 */
};

After changes, those members are correctly aligned at offset 795:

struct virtnet_info {
...
        union {
                struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
                struct {
                        unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
                        u8         rss_hash_key_data[40]; /*   795    40 */
                };                                       /*   792    43 */
        };                                               /*   792    44 */
...
        /* size: 840, cachelines: 14, members: 47 */
        /* sum members: 801, holes: 8, sum holes: 35 */
        /* padding: 4 */
        /* paddings: 1, sum paddings: 4 */
        /* last cacheline: 8 bytes */
};

As a result, the RSS key passed to the device is shifted by 1
byte: the last byte is cut off, and instead a (possibly
uninitialized) byte is added at the beginning.

As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
moved to the end, since it seems those three members should stick
around together. :)

Cc: stable@vger.kernel.org
Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
Changes in v2:
 - Update subject and changelog text (include feedback from Simon and
   Michael --thanks folks)
 - Add Fixes tag and CC -stable.

v1:
 - Link: https://lore.kernel.org/linux-hardening/aLiYrQGdGmaDTtLF@kspp/

 drivers/net/virtio_net.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 22d894101c01..5cbcc9926a23 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -425,9 +425,6 @@ struct virtnet_info {
 	u16 rss_indir_table_size;
 	u32 rss_hash_types_supported;
 	u32 rss_hash_types_saved;
-	struct virtio_net_rss_config_hdr *rss_hdr;
-	struct virtio_net_rss_config_trailer rss_trailer;
-	u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];
 
 	/* Has control virtqueue */
 	bool has_cvq;
@@ -493,7 +490,16 @@ struct virtnet_info {
 	struct failover *failover;
 
 	u64 device_stats_cap;
+
+	struct virtio_net_rss_config_hdr *rss_hdr;
+
+	/* Must be last as it ends in a flexible-array member. */
+	TRAILING_OVERLAP(struct virtio_net_rss_config_trailer, rss_trailer, hash_key_data,
+		u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];
+	);
 };
+static_assert(offsetof(struct virtnet_info, rss_trailer.hash_key_data) ==
+	      offsetof(struct virtnet_info, rss_hash_key_data));
 
 struct padded_vnet_hdr {
 	struct virtio_net_hdr_v1_hash hdr;
-- 
2.43.0
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Michael S. Tsirkin 3 weeks, 6 days ago
On Sat, Jan 10, 2026 at 05:07:17PM +0900, Gustavo A. R. Silva wrote:
> Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
> along with the following warning:
> 
> drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> 
> This helper creates a union between a flexible-array member (FAM)
> and a set of members that would otherwise follow it (in this case
> `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
> overlays the trailing members (rss_hash_key_data) onto the FAM
> (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
> The static_assert() ensures this alignment remains.
> 
> Notice that due to tail padding in flexible `struct
> virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
> (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
> offset 84 in struct virtnet_info) are misaligned by one byte. See
> below:
> 
> struct virtio_net_rss_config_trailer {
>         __le16                     max_tx_vq;            /*     0     2 */
>         __u8                       hash_key_length;      /*     2     1 */
>         __u8                       hash_key_data[];      /*     3     0 */
> 
>         /* size: 4, cachelines: 1, members: 3 */
>         /* padding: 1 */
>         /* last cacheline: 4 bytes */
> };
> 
> struct virtnet_info {
> ...
>         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
> 
>         /* XXX last struct has 1 byte of padding */
> 
>         u8                         rss_hash_key_data[40]; /*    84    40 */
> ...
>         /* size: 832, cachelines: 13, members: 48 */
>         /* sum members: 801, holes: 8, sum holes: 31 */
>         /* paddings: 2, sum paddings: 5 */
> };
> 
> After changes, those members are correctly aligned at offset 795:
> 
> struct virtnet_info {
> ...
>         union {
>                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
>                 struct {
>                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
>                         u8         rss_hash_key_data[40]; /*   795    40 */
>                 };                                       /*   792    43 */
>         };                                               /*   792    44 */
> ...
>         /* size: 840, cachelines: 14, members: 47 */
>         /* sum members: 801, holes: 8, sum holes: 35 */
>         /* padding: 4 */
>         /* paddings: 1, sum paddings: 4 */
>         /* last cacheline: 8 bytes */
> };
> 
> As a result, the RSS key passed to the device is shifted by 1
> byte: the last byte is cut off, and instead a (possibly
> uninitialized) byte is added at the beginning.
> 
> As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
> moved to the end, since it seems those three members should stick
> around together. :)
> 
> Cc: stable@vger.kernel.org
> Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---

Seems to belong in net, not next.

Besides that:

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> Changes in v2:
>  - Update subject and changelog text (include feedback from Simon and
>    Michael --thanks folks)
>  - Add Fixes tag and CC -stable.
> 
> v1:
>  - Link: https://lore.kernel.org/linux-hardening/aLiYrQGdGmaDTtLF@kspp/
> 
>  drivers/net/virtio_net.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 22d894101c01..5cbcc9926a23 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -425,9 +425,6 @@ struct virtnet_info {
>  	u16 rss_indir_table_size;
>  	u32 rss_hash_types_supported;
>  	u32 rss_hash_types_saved;
> -	struct virtio_net_rss_config_hdr *rss_hdr;
> -	struct virtio_net_rss_config_trailer rss_trailer;
> -	u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];
>  
>  	/* Has control virtqueue */
>  	bool has_cvq;
> @@ -493,7 +490,16 @@ struct virtnet_info {
>  	struct failover *failover;
>  
>  	u64 device_stats_cap;
> +
> +	struct virtio_net_rss_config_hdr *rss_hdr;
> +
> +	/* Must be last as it ends in a flexible-array member. */
> +	TRAILING_OVERLAP(struct virtio_net_rss_config_trailer, rss_trailer, hash_key_data,
> +		u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];
> +	);
>  };
> +static_assert(offsetof(struct virtnet_info, rss_trailer.hash_key_data) ==
> +	      offsetof(struct virtnet_info, rss_hash_key_data));
>  
>  struct padded_vnet_hdr {
>  	struct virtio_net_hdr_v1_hash hdr;
> -- 
> 2.43.0
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Paolo Abeni 4 weeks ago
On 1/10/26 9:07 AM, Gustavo A. R. Silva wrote:
> Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
> along with the following warning:
> 
> drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> 
> This helper creates a union between a flexible-array member (FAM)
> and a set of members that would otherwise follow it (in this case
> `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
> overlays the trailing members (rss_hash_key_data) onto the FAM
> (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
> The static_assert() ensures this alignment remains.
> 
> Notice that due to tail padding in flexible `struct
> virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
> (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
> offset 84 in struct virtnet_info) are misaligned by one byte. See
> below:
> 
> struct virtio_net_rss_config_trailer {
>         __le16                     max_tx_vq;            /*     0     2 */
>         __u8                       hash_key_length;      /*     2     1 */
>         __u8                       hash_key_data[];      /*     3     0 */
> 
>         /* size: 4, cachelines: 1, members: 3 */
>         /* padding: 1 */
>         /* last cacheline: 4 bytes */
> };
> 
> struct virtnet_info {
> ...
>         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
> 
>         /* XXX last struct has 1 byte of padding */
> 
>         u8                         rss_hash_key_data[40]; /*    84    40 */
> ...
>         /* size: 832, cachelines: 13, members: 48 */
>         /* sum members: 801, holes: 8, sum holes: 31 */
>         /* paddings: 2, sum paddings: 5 */
> };
> 
> After changes, those members are correctly aligned at offset 795:
> 
> struct virtnet_info {
> ...
>         union {
>                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
>                 struct {
>                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
>                         u8         rss_hash_key_data[40]; /*   795    40 */
>                 };                                       /*   792    43 */
>         };                                               /*   792    44 */
> ...
>         /* size: 840, cachelines: 14, members: 47 */
>         /* sum members: 801, holes: 8, sum holes: 35 */
>         /* padding: 4 */
>         /* paddings: 1, sum paddings: 4 */
>         /* last cacheline: 8 bytes */
> };
> 
> As a result, the RSS key passed to the device is shifted by 1
> byte: the last byte is cut off, and instead a (possibly
> uninitialized) byte is added at the beginning.
> 
> As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
> moved to the end, since it seems those three members should stick
> around together. :)
> 
> Cc: stable@vger.kernel.org
> Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> Changes in v2:
>  - Update subject and changelog text (include feedback from Simon and
>    Michael --thanks folks)
>  - Add Fixes tag and CC -stable.

@Michael, @Jason: This is still apparently targeting 'net-next', but I
think it should land in the 'net' tree, right?

/P
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Jason Wang 3 weeks, 6 days ago
On Tue, Jan 13, 2026 at 10:30 PM Paolo Abeni <pabeni@redhat.com> wrote:
>
> On 1/10/26 9:07 AM, Gustavo A. R. Silva wrote:
> > Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
> > along with the following warning:
> >
> > drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> >
> > This helper creates a union between a flexible-array member (FAM)
> > and a set of members that would otherwise follow it (in this case
> > `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
> > overlays the trailing members (rss_hash_key_data) onto the FAM
> > (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
> > The static_assert() ensures this alignment remains.
> >
> > Notice that due to tail padding in flexible `struct
> > virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
> > (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
> > offset 84 in struct virtnet_info) are misaligned by one byte. See
> > below:
> >
> > struct virtio_net_rss_config_trailer {
> >         __le16                     max_tx_vq;            /*     0     2 */
> >         __u8                       hash_key_length;      /*     2     1 */
> >         __u8                       hash_key_data[];      /*     3     0 */
> >
> >         /* size: 4, cachelines: 1, members: 3 */
> >         /* padding: 1 */
> >         /* last cacheline: 4 bytes */
> > };
> >
> > struct virtnet_info {
> > ...
> >         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
> >
> >         /* XXX last struct has 1 byte of padding */
> >
> >         u8                         rss_hash_key_data[40]; /*    84    40 */
> > ...
> >         /* size: 832, cachelines: 13, members: 48 */
> >         /* sum members: 801, holes: 8, sum holes: 31 */
> >         /* paddings: 2, sum paddings: 5 */
> > };
> >
> > After changes, those members are correctly aligned at offset 795:
> >
> > struct virtnet_info {
> > ...
> >         union {
> >                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
> >                 struct {
> >                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
> >                         u8         rss_hash_key_data[40]; /*   795    40 */
> >                 };                                       /*   792    43 */
> >         };                                               /*   792    44 */
> > ...
> >         /* size: 840, cachelines: 14, members: 47 */
> >         /* sum members: 801, holes: 8, sum holes: 35 */
> >         /* padding: 4 */
> >         /* paddings: 1, sum paddings: 4 */
> >         /* last cacheline: 8 bytes */
> > };
> >
> > As a result, the RSS key passed to the device is shifted by 1
> > byte: the last byte is cut off, and instead a (possibly
> > uninitialized) byte is added at the beginning.
> >
> > As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
> > moved to the end, since it seems those three members should stick
> > around together. :)
> >
> > Cc: stable@vger.kernel.org
> > Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
> > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> > ---
> > Changes in v2:
> >  - Update subject and changelog text (include feedback from Simon and
> >    Michael --thanks folks)
> >  - Add Fixes tag and CC -stable.
>
> @Michael, @Jason: This is still apparently targeting 'net-next', but I
> think it should land in the 'net' tree, right?

Right.

Thanks

>
> /P
>
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Michael S. Tsirkin 4 weeks ago
On Tue, Jan 13, 2026 at 03:30:00PM +0100, Paolo Abeni wrote:
> On 1/10/26 9:07 AM, Gustavo A. R. Silva wrote:
> > Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
> > along with the following warning:
> > 
> > drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> > 
> > This helper creates a union between a flexible-array member (FAM)
> > and a set of members that would otherwise follow it (in this case
> > `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
> > overlays the trailing members (rss_hash_key_data) onto the FAM
> > (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
> > The static_assert() ensures this alignment remains.
> > 
> > Notice that due to tail padding in flexible `struct
> > virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
> > (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
> > offset 84 in struct virtnet_info) are misaligned by one byte. See
> > below:
> > 
> > struct virtio_net_rss_config_trailer {
> >         __le16                     max_tx_vq;            /*     0     2 */
> >         __u8                       hash_key_length;      /*     2     1 */
> >         __u8                       hash_key_data[];      /*     3     0 */
> > 
> >         /* size: 4, cachelines: 1, members: 3 */
> >         /* padding: 1 */
> >         /* last cacheline: 4 bytes */
> > };
> > 
> > struct virtnet_info {
> > ...
> >         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
> > 
> >         /* XXX last struct has 1 byte of padding */
> > 
> >         u8                         rss_hash_key_data[40]; /*    84    40 */
> > ...
> >         /* size: 832, cachelines: 13, members: 48 */
> >         /* sum members: 801, holes: 8, sum holes: 31 */
> >         /* paddings: 2, sum paddings: 5 */
> > };
> > 
> > After changes, those members are correctly aligned at offset 795:
> > 
> > struct virtnet_info {
> > ...
> >         union {
> >                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
> >                 struct {
> >                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
> >                         u8         rss_hash_key_data[40]; /*   795    40 */
> >                 };                                       /*   792    43 */
> >         };                                               /*   792    44 */
> > ...
> >         /* size: 840, cachelines: 14, members: 47 */
> >         /* sum members: 801, holes: 8, sum holes: 35 */
> >         /* padding: 4 */
> >         /* paddings: 1, sum paddings: 4 */
> >         /* last cacheline: 8 bytes */
> > };
> > 
> > As a result, the RSS key passed to the device is shifted by 1
> > byte: the last byte is cut off, and instead a (possibly
> > uninitialized) byte is added at the beginning.
> > 
> > As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
> > moved to the end, since it seems those three members should stick
> > around together. :)
> > 
> > Cc: stable@vger.kernel.org
> > Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
> > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> > ---
> > Changes in v2:
> >  - Update subject and changelog text (include feedback from Simon and
> >    Michael --thanks folks)
> >  - Add Fixes tag and CC -stable.
> 
> @Michael, @Jason: This is still apparently targeting 'net-next', but I
> think it should land in the 'net' tree, right?
> 
> /P

Probably but I'm yet to properly review it. The thing that puzzles me at
a first glance is how are things working right now then?

-- 
MST
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Paolo Abeni 4 weeks ago
On 1/13/26 3:39 PM, Michael S. Tsirkin wrote:
> On Tue, Jan 13, 2026 at 03:30:00PM +0100, Paolo Abeni wrote:
>> On 1/10/26 9:07 AM, Gustavo A. R. Silva wrote:
>>> Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
>>> along with the following warning:
>>>
>>> drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
>>>
>>> This helper creates a union between a flexible-array member (FAM)
>>> and a set of members that would otherwise follow it (in this case
>>> `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
>>> overlays the trailing members (rss_hash_key_data) onto the FAM
>>> (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
>>> The static_assert() ensures this alignment remains.
>>>
>>> Notice that due to tail padding in flexible `struct
>>> virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
>>> (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
>>> offset 84 in struct virtnet_info) are misaligned by one byte. See
>>> below:
>>>
>>> struct virtio_net_rss_config_trailer {
>>>         __le16                     max_tx_vq;            /*     0     2 */
>>>         __u8                       hash_key_length;      /*     2     1 */
>>>         __u8                       hash_key_data[];      /*     3     0 */
>>>
>>>         /* size: 4, cachelines: 1, members: 3 */
>>>         /* padding: 1 */
>>>         /* last cacheline: 4 bytes */
>>> };
>>>
>>> struct virtnet_info {
>>> ...
>>>         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
>>>
>>>         /* XXX last struct has 1 byte of padding */
>>>
>>>         u8                         rss_hash_key_data[40]; /*    84    40 */
>>> ...
>>>         /* size: 832, cachelines: 13, members: 48 */
>>>         /* sum members: 801, holes: 8, sum holes: 31 */
>>>         /* paddings: 2, sum paddings: 5 */
>>> };
>>>
>>> After changes, those members are correctly aligned at offset 795:
>>>
>>> struct virtnet_info {
>>> ...
>>>         union {
>>>                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
>>>                 struct {
>>>                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
>>>                         u8         rss_hash_key_data[40]; /*   795    40 */
>>>                 };                                       /*   792    43 */
>>>         };                                               /*   792    44 */
>>> ...
>>>         /* size: 840, cachelines: 14, members: 47 */
>>>         /* sum members: 801, holes: 8, sum holes: 35 */
>>>         /* padding: 4 */
>>>         /* paddings: 1, sum paddings: 4 */
>>>         /* last cacheline: 8 bytes */
>>> };
>>>
>>> As a result, the RSS key passed to the device is shifted by 1
>>> byte: the last byte is cut off, and instead a (possibly
>>> uninitialized) byte is added at the beginning.
>>>
>>> As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
>>> moved to the end, since it seems those three members should stick
>>> around together. :)
>>>
>>> Cc: stable@vger.kernel.org
>>> Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
>>> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
>>> ---
>>> Changes in v2:
>>>  - Update subject and changelog text (include feedback from Simon and
>>>    Michael --thanks folks)
>>>  - Add Fixes tag and CC -stable.
>>
>> @Michael, @Jason: This is still apparently targeting 'net-next', but I
>> think it should land in the 'net' tree, right?
>>
>> /P
> 
> Probably but I'm yet to properly review it. The thing that puzzles me at
> a first glance is how are things working right now then?

Apparently they aren't ?!?

rss self-tests for virtio_net are failing:

https://netdev-ctrl.bots.linux.dev/logs/vmksft/drv-hw-dbg/results/471521/15-rss-api-py/stdout

but the result is into the CI reported as success (no idea why?!?)

/P
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Jakub Kicinski 4 weeks ago
On Tue, 13 Jan 2026 16:06:05 +0100 Paolo Abeni wrote:
> > Probably but I'm yet to properly review it. The thing that puzzles me at
> > a first glance is how are things working right now then?  
> 
> Apparently they aren't ?!?
> 
> rss self-tests for virtio_net are failing:
> 
> https://netdev-ctrl.bots.linux.dev/logs/vmksft/drv-hw-dbg/results/471521/15-rss-api-py/stdout
> 
> but the result is into the CI reported as success (no idea why?!?)

To be clear this is a HW test so the fact that it shows up in CI as
green means just that the 2 sub cases (per [1]) which the CI judged 
to be stable and passing are still passing. The other 10 sub cases 
have never passed and still don't. IDK if you QEMU doesn't support 
RSS or it's something else but AFAICT this patch doesn't appear to 
make a difference to us.

[1] https://netdev.bots.linux.dev/devices.html

You can see the per-case breakdown of the history here (including 
the ignored sub-cases):
https://netdev.bots.linux.dev/flakes.html?tn-needle=drv-hw%2Fselftests-drivers-net-hw%2Frss-api-py&min-flip=0&br-pfx=net-next-hw&ld-cases=1
Re: [PATCH v2][next] virtio_net: Fix misalignment bug in struct virtnet_info
Posted by Michael S. Tsirkin 4 weeks ago
On Tue, Jan 13, 2026 at 04:06:05PM +0100, Paolo Abeni wrote:
> On 1/13/26 3:39 PM, Michael S. Tsirkin wrote:
> > On Tue, Jan 13, 2026 at 03:30:00PM +0100, Paolo Abeni wrote:
> >> On 1/10/26 9:07 AM, Gustavo A. R. Silva wrote:
> >>> Use the new TRAILING_OVERLAP() helper to fix a misalignment bug
> >>> along with the following warning:
> >>>
> >>> drivers/net/virtio_net.c:429:46: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> >>>
> >>> This helper creates a union between a flexible-array member (FAM)
> >>> and a set of members that would otherwise follow it (in this case
> >>> `u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE];`). This
> >>> overlays the trailing members (rss_hash_key_data) onto the FAM
> >>> (hash_key_data) while keeping the FAM and the start of MEMBERS aligned.
> >>> The static_assert() ensures this alignment remains.
> >>>
> >>> Notice that due to tail padding in flexible `struct
> >>> virtio_net_rss_config_trailer`, `rss_trailer.hash_key_data`
> >>> (at offset 83 in struct virtnet_info) and `rss_hash_key_data` (at
> >>> offset 84 in struct virtnet_info) are misaligned by one byte. See
> >>> below:
> >>>
> >>> struct virtio_net_rss_config_trailer {
> >>>         __le16                     max_tx_vq;            /*     0     2 */
> >>>         __u8                       hash_key_length;      /*     2     1 */
> >>>         __u8                       hash_key_data[];      /*     3     0 */
> >>>
> >>>         /* size: 4, cachelines: 1, members: 3 */
> >>>         /* padding: 1 */
> >>>         /* last cacheline: 4 bytes */
> >>> };
> >>>
> >>> struct virtnet_info {
> >>> ...
> >>>         struct virtio_net_rss_config_trailer rss_trailer; /*    80     4 */
> >>>
> >>>         /* XXX last struct has 1 byte of padding */
> >>>
> >>>         u8                         rss_hash_key_data[40]; /*    84    40 */
> >>> ...
> >>>         /* size: 832, cachelines: 13, members: 48 */
> >>>         /* sum members: 801, holes: 8, sum holes: 31 */
> >>>         /* paddings: 2, sum paddings: 5 */
> >>> };
> >>>
> >>> After changes, those members are correctly aligned at offset 795:
> >>>
> >>> struct virtnet_info {
> >>> ...
> >>>         union {
> >>>                 struct virtio_net_rss_config_trailer rss_trailer; /*   792     4 */
> >>>                 struct {
> >>>                         unsigned char __offset_to_hash_key_data[3]; /*   792     3 */
> >>>                         u8         rss_hash_key_data[40]; /*   795    40 */
> >>>                 };                                       /*   792    43 */
> >>>         };                                               /*   792    44 */
> >>> ...
> >>>         /* size: 840, cachelines: 14, members: 47 */
> >>>         /* sum members: 801, holes: 8, sum holes: 35 */
> >>>         /* padding: 4 */
> >>>         /* paddings: 1, sum paddings: 4 */
> >>>         /* last cacheline: 8 bytes */
> >>> };
> >>>
> >>> As a result, the RSS key passed to the device is shifted by 1
> >>> byte: the last byte is cut off, and instead a (possibly
> >>> uninitialized) byte is added at the beginning.
> >>>
> >>> As a last note `struct virtio_net_rss_config_hdr *rss_hdr;` is also
> >>> moved to the end, since it seems those three members should stick
> >>> around together. :)
> >>>
> >>> Cc: stable@vger.kernel.org
> >>> Fixes: ed3100e90d0d ("virtio_net: Use new RSS config structs")
> >>> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> >>> ---
> >>> Changes in v2:
> >>>  - Update subject and changelog text (include feedback from Simon and
> >>>    Michael --thanks folks)
> >>>  - Add Fixes tag and CC -stable.
> >>
> >> @Michael, @Jason: This is still apparently targeting 'net-next', but I
> >> think it should land in the 'net' tree, right?
> >>
> >> /P
> > 
> > Probably but I'm yet to properly review it. The thing that puzzles me at
> > a first glance is how are things working right now then?
> 
> Apparently they aren't ?!?
> 
> rss self-tests for virtio_net are failing:
> 
> https://netdev-ctrl.bots.linux.dev/logs/vmksft/drv-hw-dbg/results/471521/15-rss-api-py/stdout
> 
> but the result is into the CI reported as success (no idea why?!?)
> 
> /P

and this fixes it?