Skip to content

Conversation

@roxanan1996
Copy link
Contributor

@roxanan1996 roxanan1996 commented Dec 10, 2025

DESCRIPTION

Commit 2ea3528 ("skbuff: skb_segment, Call zero copy functions before using skbuff frags") is the CVE fix.
But it was not a clean cherry pick.
First 2 commits are prereq, and the second one
9e4b7a9 ("net: gso: fix panic on frag_list with mixed head alloc types")
is a fix for CVE-2022-49872 itself, so backporting the prereq is safe.

COMMITS

net: Pass NULL to skb_network_protocol() when we don't care about vlan depth

jira VULN-66198
cve-pre CVE-2022-49872
commit-author Miaohe Lin <linmiaohe@huawei.com>
commit 2f631133c40cd8e311ae393518c3e651e476ab66
net: gso: fix panic on frag_list with mixed head alloc types

jira VULN-66198
cve CVE-2022-49872
commit-author Jiri Benc <jbenc@redhat.com>
commit 9e4b7a99a03aefd37ba7bb1f022c8efab5019165
skbuff: skb_segment, Call zero copy functions before using skbuff frags

jira VULN-155407
cve CVE-2023-53354
commit-author Mohamed Khalfella <mkhalfella@purestorage.com>
commit 2ea35288c83b3d501a88bc17f2df8f176b5cc96f

TESTING

BUILD

> grep -E -B 5 -A 5 '\[TIMER\]|^Starting Build' /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kernel-build-after.log
/home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kernel-src-tree
Skipping make mrproper
[TIMER]{MRPROPER}: 0s
x86_64 architecture detected, copying config
'configs/kernel-x86_64.config' -> '.config'
Setting Local Version for build
CONFIG_LOCALVERSION="-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11"
Making olddefconfig
scripts/kconfig/conf  --olddefconfig Kconfig
#
# configuration written to .config
#
Starting Build
scripts/kconfig/conf  --syncconfig Kconfig
  DESCEND objtool
  DESCEND bpf/resolve_btfids
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
--
arch/x86/tools/insn_sanity: Success: decoded and checked 1000000 random instructions with 0 errors (seed:0xc4f1f4ab)
Kernel: arch/x86/boot/bzImage is ready  (#1)
WARNING: "netif_napi_del" [vmlinux] is a static EXPORT_SYMBOL
  CC      drivers/gpu/drm/radeon/radeon.mod.o
  LD [M]  drivers/gpu/drm/radeon/radeon.ko
[TIMER]{BUILD}: 45s
Making Modules
  INSTALL arch/x86/crypto/blowfish-x86_64.ko
  INSTALL arch/x86/crypto/camellia-aesni-avx-x86_64.ko
  INSTALL arch/x86/crypto/camellia-aesni-avx2.ko
  INSTALL arch/x86/crypto/camellia-x86_64.ko
--
  INSTALL sound/virtio/virtio_snd.ko
  INSTALL sound/xen/snd_xen_front.ko
  INSTALL sound/x86/snd-hdmi-lpe-audio.ko
  INSTALL virt/lib/irqbypass.ko
  DEPMOD  4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+
[TIMER]{MODULES}: 9s
Making Install
sh ./arch/x86/boot/install.sh 4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+ arch/x86/boot/bzImage \
	System.map "/boot"
[TIMER]{INSTALL}: 31s
Checking kABI
kABI check passed
Setting Default Kernel to /boot/vmlinuz-4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+ and Index to 0
The default is /boot/loader/entries/7ec8589fb2294392a79c575c5d06592a-4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+.conf with index 0 and kernel /boot/vmlinuz-4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+
The default is /boot/loader/entries/7ec8589fb2294392a79c575c5d06592a-4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+.conf with index 0 and kernel /boot/vmlinuz-4.18.0-rnicolescu_ciqlts8_6_CVE-2023-53354-e3989e6257f11+
Generating grub configuration file ...
done
Hopefully Grub2.0 took everything ... rebooting after time metrices
[TIMER]{MRPROPER}: 0s
[TIMER]{BUILD}: 45s
[TIMER]{MODULES}: 9s
[TIMER]{INSTALL}: 31s
[TIMER]{TOTAL} 88s
Rebooting in 10 seconds

Kselftests

> /home/rnicolescu/ciq/kernel-tools/kselftest-diff.sh /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354
/home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kselftest-before.log
212
/home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kselftest-after.log
212
Before: /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kselftest-before.log
After: /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kselftest-after.log
Diff:
No differences found.

Check_kernel_commits

> python3 /home/rnicolescu/ciq/kernel-src-tree-tools/check_kernel_commits.py --repo /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kernel-src-tree --pr_branch {rnicolescu}_ciqlts8_6_CVE-2023-53354 --base_branch origin/ciqlts8_6 --check-cves
All referenced commits exist upstream and have no Fixes: tags.

Run interdiff

> python3 /home/rnicolescu/ciq/kernel-src-tree-tools/run_interdiff.py --repo /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kernel-src-tree --pr_branch {rnicolescu}_ciqlts8_6_CVE-2023-53354 --base_branch origin/ciqlts8_6
[DIFF] PR commit e3989e6257f11 (skbuff: skb_segment, Call zero copy functions before using skbuff frags) → upstream 2ea35288c83b
Differences found:

  diff -u b/net/core/skbuff.c b/net/core/skbuff.c
  --- b/net/core/skbuff.c
  +++ b/net/core/skbuff.c
  @@ -4070,5 +4070,18446744073709551615 @@
  -		skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
  -					   SKBFL_SHARED_FRAG;
  +		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
  +					      SKBTX_SHARED_FRAG;
   
   		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
   		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
  @@ -4073,9 +4079,8 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
   		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
   					      SKBTX_SHARED_FRAG;
   
  -		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
  -		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
  +		if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
   			goto err;
   
   		while (pos < offset + len) {
   			if (i >= nfrags) {
  @@ -4639,9 +4645,8 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
   		skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
   					   SKBFL_SHARED_FRAG;
   
  -		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
  -		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
  +		if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
   			goto err;
   
   		while (pos < offset + len) {
   			if (i >= nfrags) {
  @@ -4653,0 +4087,6 @@
  +					i--;
  +					frag--;
  +				}
  +
  +				list_skb = list_skb->next;
  +			}

First part is due to missing commit 06b4feb ("net: group skb_shinfo zerocopy related bits together.")
which is more a move of zerocopy bits out of tx_flags to flag. It is not necessary.
The second is because hunks are rejected, bug in interdiff.
The third is also a bug, not sure, because that's not even modified code.

Check colordiff log for more details
colordiff.log

Run jira_pr_check

> python3 /home/rnicolescu/ciq/kernel-src-tree-tools/jira_pr_check.py --kernel-src-tree /home/rnicolescu/ciq/kernels/lts-8.6_CVE-2023-53354/kernel-src-tree --merge-target {rnicolescu}_ciqlts8_6_CVE-2023-53354 --pr-branch origin/ciqlts8_6

## JIRA PR Check Results

✅ **No issues found!**


---
**Summary:** Checked 0 commit(s) total.

…n depth

jira VULN-66198
cve-pre CVE-2022-49872
commit-author Miaohe Lin <linmiaohe@huawei.com>
commit 2f63113

When we don't care about vlan depth, we could pass NULL instead of the
address of a unused local variable to skb_network_protocol() as a param.

	Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 2f63113)
	Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
jira VULN-66198
cve CVE-2022-49872
commit-author Jiri Benc <jbenc@redhat.com>
commit 9e4b7a9

Since commit 3dcbdb1 ("net: gso: Fix skb_segment splat when
splitting gso_size mangled skb having linear-headed frag_list"), it is
allowed to change gso_size of a GRO packet. However, that commit assumes
that "checking the first list_skb member suffices; i.e if either of the
list_skb members have non head_frag head, then the first one has too".

It turns out this assumption does not hold. We've seen BUG_ON being hit
in skb_segment when skbs on the frag_list had differing head_frag with
the vmxnet3 driver. This happens because __netdev_alloc_skb and
__napi_alloc_skb can return a skb that is page backed or kmalloced
depending on the requested size. As the result, the last small skb in
the GRO packet can be kmalloced.

There are three different locations where this can be fixed:

(1) We could check head_frag in GRO and not allow GROing skbs with
    different head_frag. However, that would lead to performance
    regression on normal forward paths with unmodified gso_size, where
    !head_frag in the last packet is not a problem.

(2) Set a flag in bpf_skb_net_grow and bpf_skb_net_shrink indicating
    that NETIF_F_SG is undesirable. That would need to eat a bit in
    sk_buff. Furthermore, that flag can be unset when all skbs on the
    frag_list are page backed. To retain good performance,
    bpf_skb_net_grow/shrink would have to walk the frag_list.

(3) Walk the frag_list in skb_segment when determining whether
    NETIF_F_SG should be cleared. This of course slows things down.

This patch implements (3). To limit the performance impact in
skb_segment, the list is walked only for skbs with SKB_GSO_DODGY set
that have gso_size changed. Normal paths thus will not hit it.

We could check only the last skb but since we need to walk the whole
list anyway, let's stay on the safe side.

Fixes: 3dcbdb1 ("net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list")
	Signed-off-by: Jiri Benc <jbenc@redhat.com>
	Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://lore.kernel.org/r/e04426a6a91baf4d1081e1b478c82b5de25fdf21.1667407944.git.jbenc@redhat.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 9e4b7a9)
	Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
jira VULN-155407
cve CVE-2023-53354
commit-author Mohamed Khalfella <mkhalfella@purestorage.com>
commit 2ea3528

Commit bf5c25d ("skbuff: in skb_segment, call zerocopy functions
once per nskb") added the call to zero copy functions in skb_segment().
The change introduced a bug in skb_segment() because skb_orphan_frags()
may possibly change the number of fragments or allocate new fragments
altogether leaving nrfrags and frag to point to the old values. This can
cause a panic with stacktrace like the one below.

[  193.894380] BUG: kernel NULL pointer dereference, address: 00000000000000bc
[  193.895273] CPU: 13 PID: 18164 Comm: vh-net-17428 Kdump: loaded Tainted: G           O      5.15.123+ #26
[  193.903919] RIP: 0010:skb_segment+0xb0e/0x12f0
[  194.021892] Call Trace:
[  194.027422]  <TASK>
[  194.072861]  tcp_gso_segment+0x107/0x540
[  194.082031]  inet_gso_segment+0x15c/0x3d0
[  194.090783]  skb_mac_gso_segment+0x9f/0x110
[  194.095016]  __skb_gso_segment+0xc1/0x190
[  194.103131]  netem_enqueue+0x290/0xb10 [sch_netem]
[  194.107071]  dev_qdisc_enqueue+0x16/0x70
[  194.110884]  __dev_queue_xmit+0x63b/0xb30
[  194.121670]  bond_start_xmit+0x159/0x380 [bonding]
[  194.128506]  dev_hard_start_xmit+0xc3/0x1e0
[  194.131787]  __dev_queue_xmit+0x8a0/0xb30
[  194.138225]  macvlan_start_xmit+0x4f/0x100 [macvlan]
[  194.141477]  dev_hard_start_xmit+0xc3/0x1e0
[  194.144622]  sch_direct_xmit+0xe3/0x280
[  194.147748]  __dev_queue_xmit+0x54a/0xb30
[  194.154131]  tap_get_user+0x2a8/0x9c0 [tap]
[  194.157358]  tap_sendmsg+0x52/0x8e0 [tap]
[  194.167049]  handle_tx_zerocopy+0x14e/0x4c0 [vhost_net]
[  194.173631]  handle_tx+0xcd/0xe0 [vhost_net]
[  194.176959]  vhost_worker+0x76/0xb0 [vhost]
[  194.183667]  kthread+0x118/0x140
[  194.190358]  ret_from_fork+0x1f/0x30
[  194.193670]  </TASK>

In this case calling skb_orphan_frags() updated nr_frags leaving nrfrags
local variable in skb_segment() stale. This resulted in the code hitting
i >= nrfrags prematurely and trying to move to next frag_skb using
list_skb pointer, which was NULL, and caused kernel panic. Move the call
to zero copy functions before using frags and nr_frags.

Fixes: bf5c25d ("skbuff: in skb_segment, call zerocopy functions once per nskb")
	Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
	Reported-by: Amit Goyal <agoyal@purestorage.com>
	Cc: stable@vger.kernel.org
	Reviewed-by: Eric Dumazet <edumazet@google.com>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 2ea3528)
	Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
@roxanan1996 roxanan1996 marked this pull request as draft December 10, 2025 14:50
@github-actions
Copy link

🔍 Interdiff Analysis

  • ⚠️ PR commit e3989e6257f1 (skbuff: skb_segment, Call zero copy functions before using skbuff frags) → upstream 2ea35288c83b
    Differences found:
diff -u b/net/core/skbuff.c b/net/core/skbuff.c
--- b/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4070,5 +4070,18446744073709551615 @@
-		skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
-					   SKBFL_SHARED_FRAG;
+		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
+					      SKBTX_SHARED_FRAG;
 
 		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
 		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
@@ -4073,9 +4079,8 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 		skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags &
 					      SKBTX_SHARED_FRAG;
 
-		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
-		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
+		if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
 			goto err;
 
 		while (pos < offset + len) {
 			if (i >= nfrags) {
@@ -4639,9 +4645,8 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
 					   SKBFL_SHARED_FRAG;
 
-		if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
-		    skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
+		if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
 			goto err;
 
 		while (pos < offset + len) {
 			if (i >= nfrags) {
@@ -4653,0 +4087,6 @@
+					i--;
+					frag--;
+				}
+
+				list_skb = list_skb->next;
+			}

This is an automated interdiff check for backported commits.

@roxanan1996 roxanan1996 marked this pull request as ready for review December 12, 2025 15:29
@roxanan1996 roxanan1996 requested a review from a team December 12, 2025 15:29
Copy link
Collaborator

@bmastbergen bmastbergen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants