CVE-2022-49142: net: preserve skb_end_offset() in skb_unclone_keeptruesize()
In the Linux kernel, the following vulnerability has been resolved:
net: preserve skbendoffset() in skbunclonekeeptruesize()
syzbot found another way to trigger the infamous WARNONONCE(delta < len) in skbtrycoalesce() [1]
I was able to root cause the issue to kfence.
When kfence is in action, the following assertion is no longer true:
int size = xxxx; void ptr1 = kmalloc(size, gfp); void ptr2 = kmalloc(size, gfp);
if (ptr1 && ptr2) ASSERT(ksize(ptr1) == ksize(ptr2));
We attempted to fix these issues in the blamed commits, but forgot that TCP was possibly shifting data after skbunclonekeeptruesize() has been used, notably from tcpretranstrycollapse().
So we not only need to keep same skb->truesize value, we also need to make sure TCP wont fill new tailroom that pskbexpandhead() was able to get from a addr = kmalloc(...) followed by ksize(addr)
Split skbunclonekeeptruesize() into two parts:
1) Inline skbunclonekeeptruesize() for the common case, when skb is not cloned.
2) Out of line skbunclonekeeptruesize() for the 'slow path'.
WARNING: CPU: 1 PID: 6490 at net/core/skbuff.c:5295 skbtrycoalesce+0x1235/0x1560 net/core/skbuff.c:5295 Modules linked in: CPU: 1 PID: 6490 Comm: syz-executor161 Not tainted 5.17.0-rc4-syzkaller-00229-g4f12b742eb2b #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:skbtrycoalesce+0x1235/0x1560 net/core/skbuff.c:5295 Code: bf 01 00 00 00 0f b7 c0 89 c6 89 44 24 20 e8 62 24 4e fa 8b 44 24 20 83 e8 01 0f 85 e5 f0 ff ff e9 87 f4 ff ff e8 cb 20 4e fa <0f> 0b e9 06 f9 ff ff e8 af b2 95 fa e9 69 f0 ff ff e8 95 b2 95 fa RSP: 0018:ffffc900063af268 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 00000000ffffffd5 RCX: 0000000000000000 RDX: ffff88806fc05700 RSI: ffffffff872abd55 RDI: 0000000000000003 RBP: ffff88806e675500 R08: 00000000ffffffd5 R09: 0000000000000000 R10: ffffffff872ab659 R11: 0000000000000000 R12: ffff88806dd554e8 R13: ffff88806dd9bac0 R14: ffff88806dd9a2c0 R15: 0000000000000155 FS: 00007f18014f9700(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020002000 CR3: 000000006be7a000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> tcptrycoalesce net/ipv4/tcpinput.c:4651 [inline] tcptrycoalesce+0x393/0x920 net/ipv4/tcpinput.c:4630 tcpqueuercv+0x8a/0x6e0 net/ipv4/tcpinput.c:4914 tcpdataqueue+0x11fd/0x4bb0 net/ipv4/tcpinput.c:5025 tcprcvestablished+0x81e/0x1ff0 net/ipv4/tcpinput.c:5947 tcpv4dorcv+0x65e/0x980 net/ipv4/tcpipv4.c:1719 skbacklogrcv include/net/sock.h:1037 [inline] releasesock+0x134/0x3b0 net/core/sock.c:2779 releasesock+0x54/0x1b0 net/core/sock.c:3311 skwaitdata+0x177/0x450 net/core/sock.c:2821 tcprecvmsglocked+0xe28/0x1fd0 net/ipv4/tcp.c:2457 tcprecvmsg+0x137/0x610 net/ipv4/tcp.c:2572 inetrecvmsg+0x11b/0x5e0 net/ipv4/afinet.c:850 sockrecvmsgnosec net/socket.c:948 [inline] sockrecvmsg net/socket.c:966 [inline] sockrecvmsg net/socket.c:962 [inline] sysrecvmsg+0x2c4/0x600 net/socket.c:2632 sysrecvmsg+0x127/0x200 net/socket.c:2674 sysrecvmsg+0xe2/0x1a0 net/socket.c:2704 dosyscallx64 arch/x86/entry/common.c:50 [inline] dosyscall64+0x35/0xb0 arch/x86/entry/common.c:80 entrySYSCALL64afterhwframe+0x44/0xae
Affected Software
Event History
Frequently Asked Questions
What access does an attacker need to exploit this issue?
The CVSS vector rates the issue as network-accessible with low attack complexity and no required privileges or user interaction. The provided information does not identify a specific protocol exchange or packet pattern needed to trigger it.
What security impact is indicated by the CVSS assessment?
The assessment indicates a high availability impact, with no confidentiality or integrity impact. This is consistent with a kernel networking failure condition rather than disclosure or modification of data.
How can administrators look for evidence of the issue?
The reported failure produces a kernel warning at skb_try_coalesce(), specifically WARN_ON_ONCE(delta < len), with a stack trace referencing net/core/skbuff.c. The description associates the condition with TCP data shifting after skb_unclone_keeptruesize(), and notes that KFENCE can affect the relevant allocation-size assumption.