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&amp;#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&amp;#39;s stay on the safe side.

Impact