> syzkaller hit the following crash on > 37759fa6d0fa9e4d6036d19ac12f555bfc0aeafd > git://git.cmpxchg.org/linux-mmots.git/master > compiler: gcc (GCC) 7.1.1 20170620 > .config is attached > Raw console output is attached. > C reproducer is attached > syzkaller reproducer is attached. See https://goo.gl/kgGztJ > for information about syzkaller reproducers Reproduced with the C reproducer on v4.15-rc1 and mainline going back at least to v4.8, but not v4.7. SCTP GSO was introduced in v4.8-rc1, so a patch in this set is likely the starting point. Indeed crashes at 90017accff61 ("sctp: Add GSO support"), but not at 90017accff61~4. The reproducer with its sandbox removed shows this invocation in strace -f # strace -f ./repro2 [... skipped ...] socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 open("/dev/net/tun", O_RDONLY) = 4 fcntl(4, F_DUPFD, 3) = 5 socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC, 8) = 6 ioctl(4, TUNSETIFF, 0x20e63000) = 0 ioctl(3, SIOCSIFFLAGS, {ifr_name="syz0", ifr_flags=IFF_UP|IFF_PROMISC|IFF_ALLMULTI}) = 0 setsockopt(6, SOL_PACKET, 0xf /* PACKET_??? */, [4096], 4) = 0 ioctl(6, SIOCGIFINDEX, {ifr_name="syz0", ifr_index=24}) = 0 bind(6, {sa_family=AF_PACKET, proto=0000, if24, pkttype=PACKET_HOST, addr(6)={1, aaaaaaaaaa00}, 20) = 0 dup2(6, 5) = 5 write(5, "\0\201\1\0\350\367\0\0\3\0E\364\0 \0d\0\0\7\2042\342\0\0\0 \177\0\0\1\0\t"..., 42 where 0xf in setsockopt is PACKET_VNET_HDR So this is a packet socket writing something that apparently looks like an SCTP packet, is only 42 bytes long, but has GSO set in its virtio_net_hdr struct. It crashes in skb_segment seemingly on a NULL list_skb. (gdb) list *(skb_segment+0x2a4) 0xffffffff8167cc24 is in skb_segment (net/core/skbuff.c:3566). 3561 if (hsize < 0) 3562 hsize = 0; 3563 if (hsize > len || !sg) 3564 hsize = len; 3565 3566 if (!hsize && i >= nfrags && skb_headlen(list_skb) && 3567 (skb_headlen(list_skb) == len || sg)) { 3568 BUG_ON(skb_headlen(list_skb) > len); 3569 3570 i = 0; Likely there is a hidden assumption about SCTP GSO packets that does not hold for such packets generated by PF_PACKET. SCTP GSO introduced the GSO_BY_FRAGS mss value, so the code takes a different path for SCTP packets generated by the SCTP stack. PF_PACKET does not necessarily set gso_size to GSO_BY_FRAGS, so does not take the branch that requires list_skb to be non-zero here: if (unlikely(mss == GSO_BY_FRAGS)) { len = list_skb->len; } else { len = head_skb->len - offset; if (len > mss) len = mss; } hsize = skb_headlen(head_skb) - offset; if (hsize < 0) hsize = 0; if (hsize > len || !sg) hsize = len; if (!hsize && i >= nfrags && skb_headlen(list_skb) && (skb_headlen(list_skb) == len || sg)) { Somewhat tangential, but any PF_PACKET socket can set this magic gso_size value in its virtio_net_hdr, so if it is assumed to be an SCTP GSO specific option, setting it for a TCP GSO packet may also cause unexpected results. The crash requires a kernel with CONFIG_IP_SCTP enabled. -- To unsubscribe from this list: send the line "unsubscribe linux-sctp" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html