In the Linux kernel, the following vulnerability has been resolved:
rds: Fix inet6addrlst NULL dereference when IPv6 is disabled
When booting with the 'ipv6.disable=1' parameter, inet6addrlst is never initialized because inet6init() exits before addrconfinit() is called to initialize it. An attempt to bind an RDS socket to an ipv6 address results in a crash in __ipv6chkaddrandflags()
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] RIP: 0010:__ipv6chkaddrandflags+0x1df/0x7e0 Call Trace: <TASK> ipv6chkaddr+0x3b/0x50 rdstcpladdrcheck+0x155/0x3b0 [rdstcp] rdstransgetpreferred+0x15d/0x2d0 [rds] ? tracehardirqson+0x2d/0x110 rdsbind+0x1433/0x1d60 [rds] ? rdsremovebound+0xd50/0xd50 [rds] ? aaafperm+0x250/0x250 ? __might_fault+0xde/0x190 ? __sys_bind+0x1dc/0x210 __sys_bind+0x1dc/0x210 ? __ia32syssocketpair+0x100/0x100 ? restorefpregsfrom_fpstate+0x53/0x100 __x64sysbind+0x73/0xb0 ? syscallenterfromusermode+0x1c/0x50 dosyscall64+0x34/0x80 entrySYSCALL64afterhwframe+0x6e/0xd8 RIP: 0033:0x7f47f8269ea9 </TASK>
The following code reproduces the issue:
struct sockaddrin6 addr; s = socket(PFRDS, SOCK_SEQPACKET, 0);
memset(&addr, 0, sizeof(addr)); inetpton(AFINET6, ADDRESS, &addr.sin6addr); addr.sin6family = AFINET6; addr.sin6port = htons(PORT);
bind(s, &addr, sizeof(addr));
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with Syzkaller.