In the Linux kernel, the following vulnerability has been resolved: icmp6: Fix null-ptr-deref of ip6nullentry->rt6iidev in icmp6dev(). With some IPv6 Ext Hdr (RPL, SRv6, etc.), we can send a packet that has the link-local address as src and dst IP and will be forwarded to an external IP in the IPv6 Ext Hdr. For example, the script below generates a packet whose src IP is the link-local address and dst is updated to 11::. # for f in $(find /proc/sys/net/ -name seg6_enabled); do echo 1 > $f; done # python3 >>> from socket import * >>> from scapy.all import * >>> >>> SRCADDR = DSTADDR = "fe80::5054:ff:fe12:3456" >>> >>> pkt = IPv6(src=SRCADDR, dst=DSTADDR) >>> pkt /= IPv6ExtHdrSegmentRouting(type=4, addresses=["11::", "22::"], segleft=1) >>> >>> sk = socket(AFINET6, SOCKRAW, IPPROTORAW) >>> sk.sendto(bytes(pkt), (DSTADDR, 0)) For such a packet, we call ip6routeinput() to look up a route for the next destination in these three functions depending on the header type. * ipv6rthdrrcv() * ipv6rplsrhrcv() * ipv6srhrcv() If no route is found, ip6nullentry is set to skb, and the following dstinput(skb) calls ip6pktdrop(). Finally, in icmp6dev(), we dereference skbrt6info(skb)->rt6iidev->dev as the input device is the loopback interface. Then, we have to check if skbrt6info(skb)->rt6iidev is NULL or not to avoid NULL pointer deref for ip6nullentry. BUG: kernel NULL pointer dereference, address: 0000000000000000 PF: supervisor read access in kernel mode PF: errorcode(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 0 PID: 157 Comm: python3 Not tainted 6.4.0-11996-gb121d614371c #35 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:icmp6send (net/ipv6/icmp.c:436 net/ipv6/icmp.c:503) Code: fe ff ff 48 c7 40 30 c0 86 5d 83 e8 c6 44 1c 00 e9 c8 fc ff ff 49 8b 46 58 48 83 e0 fe 0f 84 4a fb ff ff 48 8b 80 d0 00 00 00 <48> 8b 00 44 8b 88 e0 00 00 00 e9 34 fb ff ff 4d 85 ed 0f 85 69 01 RSP: 0018:ffffc90000003c70 EFLAGS: 00000286 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 00000000000000e0 RDX: 0000000000000021 RSI: 0000000000000000 RDI: ffff888006d72a18 RBP: ffffc90000003d80 R08: 0000000000000000 R09: 0000000000000001 R10: ffffc90000003d98 R11: 0000000000000040 R12: ffff888006d72a10 R13: 0000000000000000 R14: ffff8880057fb800 R15: ffffffff835d86c0 FS: 00007f9dc72ee740(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000000057b2000 CR4: 00000000007506f0 PKRU: 55555554 Call Trace: <IRQ> ip6pktdrop (net/ipv6/route.c:4513) ipv6rthdrrcv (net/ipv6/exthdrs.c:640 net/ipv6/exthdrs.c:686) ip6protocoldeliverrcu (net/ipv6/ip6input.c:437 (discriminator 5)) ip6inputfinish (./include/linux/rcupdate.h:781 net/ipv6/ip6input.c:483) _netifreceiveskbonecore (net/core/dev.c:5455) processbacklog (./include/linux/rcupdate.h:781 net/core/dev.c:5895) _napipoll (net/core/dev.c:6460) netrxaction (net/core/dev.c:6529 net/core/dev.c:6660) _dosoftirq (./arch/x86/include/asm/jumplabel.h:27 ./include/linux/jumplabel.h:207 ./include/trace/events/irq.h:142 kernel/softirq.c:554) dosoftirq (kernel/softirq.c:454 kernel/softirq.c:441) </IRQ> <TASK> _localbhenableip (kernel/softirq.c:381) _devqueuexmit (net/core/dev.c:4231) ip6finishoutput2 (./include/net/neighbour.h:544 net/ipv6/ip6output.c:135) rawv6sendmsg (./include/net/dst.h:458 ./include/linux/netfilter.h:303 net/ipv6/raw.c:656 net/ipv6/raw.c:914) socksendmsg (net/socket.c:725 net/socket.c:748) _syssendto (net/socket.c:2134) _x64syssendto (net/socket.c:2146 net/socket.c:2142 net/socket.c:2142) dosyscall64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entrySYSCALL64afterhwframe (arch/x86/entry/entry_64.S:120) RIP: 0033:0x7f9dc751baea Code: d8 64 89 02 48 c7 c0 ff f ---truncated---