In the Linux kernel, the following vulnerability has been resolved:
tcp: Fix shift-out-of-bounds in dctcpupdatealpha().
In dctcpupdatealpha(), we use a module parameter dctcpshiftg as follows:
alpha -= minnotzero(alpha, alpha >> dctcpshiftg); ... deliveredce <<= (10 - dctcpshift_g);
It seems syzkaller started fuzzing module parameters and triggered shift-out-of-bounds [0] by setting 100 to dctcpshiftg:
memcpy((void)0x20000080, "/sys/module/tcp_dctcp/parameters/dctcp_shift_g\000", 47); res = syscall(NR_openat, /fd=/0xffffffffffffff9cul, /file=/0x20000080ul, /flags=/2ul, /mode=/0ul); memcpy((void)0x20000000, "100\000", 4); syscall(NR_write, /fd=/r[0], /val=/0x20000000ul, /len=/4ul);
Let's limit the max value of dctcpshiftg by paramsetuint_minmax().
With this patch:
# echo 10 > /sys/module/tcpdctcp/parameters/dctcpshiftg # cat /sys/module/tcpdctcp/parameters/dctcpshiftg 10 # echo 11 > /sys/module/tcpdctcp/parameters/dctcpshift_g -bash: echo: write error: Invalid argument
shift exponent 100 is too large for 32-bit type 'u32' (aka 'unsigned int') CPU: 0 PID: 8083 Comm: syz-executor345 Not tainted 6.9.0-05151-g1b294a1f3561 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Call Trace: <TASK> _dumpstack lib/dumpstack.c:88 [inline] dumpstacklvl+0x201/0x300 lib/dumpstack.c:114 ubsanepilogue lib/ubsan.c:231 [inline] _ubsanhandleshiftoutofbounds+0x346/0x3a0 lib/ubsan.c:468 dctcpupdatealpha+0x540/0x570 net/ipv4/tcpdctcp.c:143 tcpinackevent net/ipv4/tcpinput.c:3802 [inline] tcpack+0x17b1/0x3bc0 net/ipv4/tcpinput.c:3948 tcprcvstateprocess+0x57a/0x2290 net/ipv4/tcpinput.c:6711 tcpv4dorcv+0x764/0xc40 net/ipv4/tcpipv4.c:1937 skbacklogrcv include/net/sock.h:1106 [inline] _releasesock+0x20f/0x350 net/core/sock.c:2983 releasesock+0x61/0x1f0 net/core/sock.c:3549 mptcpsubflowshutdown+0x3d0/0x620 net/mptcp/protocol.c:2907 mptcpchecksenddatafin+0x225/0x410 net/mptcp/protocol.c:2976 _mptcpclose+0x238/0xad0 net/mptcp/protocol.c:3072 mptcpclose+0x2a/0x1a0 net/mptcp/protocol.c:3127 inetrelease+0x190/0x1f0 net/ipv4/afinet.c:437 _sockrelease net/socket.c:659 [inline] sockclose+0xc0/0x240 net/socket.c:1421 _fput+0x41b/0x890 fs/filetable.c:422 taskworkrun+0x23b/0x300 kernel/taskwork.c:180 exittaskwork include/linux/taskwork.h:38 [inline] doexit+0x9c8/0x2540 kernel/exit.c:878 dogroupexit+0x201/0x2b0 kernel/exit.c:1027 _dosysexitgroup kernel/exit.c:1038 [inline] _sesysexitgroup kernel/exit.c:1036 [inline] _x64sysexitgroup+0x3f/0x40 kernel/exit.c:1036 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0xe4/0x240 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x67/0x6f RIP: 0033:0x7f6c2b5005b6 Code: Unable to access opcode bytes at 0x7f6c2b50058c. RSP: 002b:00007ffe883eb948 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 00007f6c2b5862f0 RCX: 00007f6c2b5005b6 RDX: 0000000000000001 RSI: 000000000000003c RDI: 0000000000000001 RBP: 0000000000000001 R08: 00000000000000e7 R09: ffffffffffffffc0 R10: 0000000000000006 R11: 0000000000000246 R12: 00007f6c2b5862f0 R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000001 </TASK>