CVE-2022-49872
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
02/05/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: gso: fix panic on frag_list with mixed head alloc types<br />
<br />
Since commit 3dcbdb134f32 ("net: gso: Fix skb_segment splat when<br />
splitting gso_size mangled skb having linear-headed frag_list"), it is<br />
allowed to change gso_size of a GRO packet. However, that commit assumes<br />
that "checking the first list_skb member suffices; i.e if either of the<br />
list_skb members have non head_frag head, then the first one has too".<br />
<br />
It turns out this assumption does not hold. We&#39;ve seen BUG_ON being hit<br />
in skb_segment when skbs on the frag_list had differing head_frag with<br />
the vmxnet3 driver. This happens because __netdev_alloc_skb and<br />
__napi_alloc_skb can return a skb that is page backed or kmalloced<br />
depending on the requested size. As the result, the last small skb in<br />
the GRO packet can be kmalloced.<br />
<br />
There are three different locations where this can be fixed:<br />
<br />
(1) We could check head_frag in GRO and not allow GROing skbs with<br />
different head_frag. However, that would lead to performance<br />
regression on normal forward paths with unmodified gso_size, where<br />
!head_frag in the last packet is not a problem.<br />
<br />
(2) Set a flag in bpf_skb_net_grow and bpf_skb_net_shrink indicating<br />
that NETIF_F_SG is undesirable. That would need to eat a bit in<br />
sk_buff. Furthermore, that flag can be unset when all skbs on the<br />
frag_list are page backed. To retain good performance,<br />
bpf_skb_net_grow/shrink would have to walk the frag_list.<br />
<br />
(3) Walk the frag_list in skb_segment when determining whether<br />
NETIF_F_SG should be cleared. This of course slows things down.<br />
<br />
This patch implements (3). To limit the performance impact in<br />
skb_segment, the list is walked only for skbs with SKB_GSO_DODGY set<br />
that have gso_size changed. Normal paths thus will not hit it.<br />
<br />
We could check only the last skb but since we need to walk the whole<br />
list anyway, let&#39;s stay on the safe side.
Impact
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/0a9f56e525ea871d3950b90076912f5c7494f00f
- https://git.kernel.org/stable/c/50868de7dc4e7f0fcadd6029f32bf4387c102ee6
- https://git.kernel.org/stable/c/5876b7f249a1ecbbcc8e35072c3828d6526d1c3a
- https://git.kernel.org/stable/c/598d9e30927b15731e83797fbd700ecf399f42dd
- https://git.kernel.org/stable/c/65ad047fd83502447269fda8fd26c99077a9af47
- https://git.kernel.org/stable/c/9e4b7a99a03aefd37ba7bb1f022c8efab5019165
- https://git.kernel.org/stable/c/ad25a115f50800c6847e0d841c5c7992a9f7c1b3
- https://git.kernel.org/stable/c/bd5362e58721e4d0d1a37796593bd6e51536ce7a