CVE-2026-23143
N/A
Summary
In the Linux kernel, the following vulnerability has been resolved:
virtio_net: Fix misalignment bug in struct virtnet_info
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. :)
Affected Software
| Vendor | Product | Version Range | Status |
|---|---|---|---|
| Linux | Linux | ed3100e90d0d120a045a551b85eb43cf2527e885 < ae48108c2310f1dd700e0dbb655c2f1d92ed00fc | affected |
| Linux | Linux | ed3100e90d0d120a045a551b85eb43cf2527e885 < 4156c3745f06bc197094b9ee97a9584e69ed00bf | affected |
| Linux | Linux | 4c47aff10f6f0a2506dc2126c17ccd4c42bfa211 | affected |
| Linux | Linux | 6.12.91 < 6.13 | affected |
| Linux | Linux | 6.15 | affected |
| Linux | Linux | 0 < 6.15 | unaffected |
| Linux | Linux | 6.18.7 <= 6.18.* | unaffected |
| Linux | Linux | 6.19 <= * | unaffected |
Weaknesses
References
- https://git.kernel.org/stable/c/ae48108c2310f1dd700e0dbb655c2f1d92ed00fc
- https://git.kernel.org/stable/c/4156c3745f06bc197094b9ee97a9584e69ed00bf
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.