linux-sctp.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* syzkaller test panic: Linux 5.4.y
@ 2021-10-18 21:29 john.p.donnelly
  2021-10-19 15:24 ` mleitner
  0 siblings, 1 reply; 6+ messages in thread
From: john.p.donnelly @ 2021-10-18 21:29 UTC (permalink / raw)
  To: linux-sctp



Hello,

I like to report a  syzkaller test failure that introduces a panic with 
the Linux-5.4.y kernel:


strace shows this activity ;

#strace ./test-scpt

socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP) = 3
setsockopt(3, SOL_SCTP, 0x76 /* SCTP_??? */, "\0\0\0\0\7\0\0\0", 8) = 0
setsockopt(3, SOL_SCTP, 0x64 /* SCTP_??? */, 
"\n\0N#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0", 28) = 0
setsockopt(3, SOL_SCTP, 0x75 /* SCTP_??? */, "\0\0\0\0\0\0\4\20", 8) = 0
connect(3, {sa_family=AF_INET6, sin6_port=htons(20003), 
inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, 
sin6_scope_id=0}, 28) = 0
setsockopt(3, SOL_SCTP, 0x77 /* SCTP_??? */, 
"\0\0\0\0;\0)\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 734


   CPU: 0 PID: 1358 Comm: skbuff-panic Not tainted 
5.4.17-2136.301.0.el7uek.x86_64 #2
task: ffff880078bb5a00 task.stack: ffffc900006d8000
   RIP: 0010:skb_panic+0x66/0x68
   RSP: 0018:ffffc900006dbcf8 EFLAGS: 00010246
   RAX: 0000000000000086 RBX: 0000000000000000 RCX: 0000000000000000
   RDX: 0000000000000000 RSI: ffff88007e816938 RDI: ffff88007e816938
[ RBP: ffffc900006dbd18 R08: 00000000fffffffe R09: 00000000000001f6
   R10: 0000000000000005 R11: 00000000000001f5 R12: ffff880078512d00
   R13: 0000000000000052 R14: ffff88007827fc00 R15: 0000000000000070
   FS:  00007f80be10a740(0000) GS:ffff88007e800000(0000) 
knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000208c0000 CR3: 000000007937c000 CR4: 00000000000006f0
   Call Trace:
    skb_put+0x4c/0x4c
    sctp_addto_chunk+0x59/0xb0 [sctp]
    sctp_make_strreset_req+0x166/0x180 [sctp]
    sctp_send_reset_streams+0x14d/0x300 [sctp]
    sctp_setsockopt.part.21+0x101f/0x1720 [sctp]
    sctp_setsockopt+0x99/0xb0 [sctp]
    sock_common_setsockopt+0x1a/0x1c
    SyS_setsockopt+0x86/0xe6
    +0x79/0x1ae
    entry_SYSCALL_64_after_hwframe+0x151/0x0
  RIP: 0033:0x7f80bdc21be9


I am not familar with any of the sctp subsystem. It was found running 
the syzkaller fuzzing test suite.

If there is a more appropriate place to report this I can do that too. 
This test fails on just about every 4.x and 5.x kernel.  It is not
unique to 5.4.


Thank you.

John.



===

//  gcc -o  test-sctp   317ef02b0d5cbd19d445294fed91453c7f970fc3.c

// autogenerated by syzkaller (https://github.com/google/syzkaller)
//  317ef02b0d5cbd19d445294fed91453c7f970fc3.c



#define _GNU_SOURCE

#include <arpa/inet.h>
#include <endian.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <sched.h>

#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>

struct nlmsg {
   char* pos;
   int nesting;
   struct nlattr* nested[8];
   char buf[1024];
};

static struct nlmsg nlmsg;

static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
                          const void* data, int size)
{
   memset(nlmsg, 0, sizeof(*nlmsg));
   struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
   hdr->nlmsg_type = typ;
   hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
   memcpy(hdr + 1, data, size);
   nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}

static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
                          int size)
{
   struct nlattr* attr = (struct nlattr*)nlmsg->pos;
   attr->nla_len = sizeof(*attr) + size;
   attr->nla_type = typ;
   memcpy(attr + 1, data, size);
   nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}

static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t 
reply_type,
                             int* reply_len)
{
   if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
     exit(1);
   struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
   hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
   struct sockaddr_nl addr;
   memset(&addr, 0, sizeof(addr));
   addr.nl_family = AF_NETLINK;
   printf ("sending : %d\n", hdr->nlmsg_len);
   unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
                       (struct sockaddr*)&addr, sizeof(addr));
   if (n != hdr->nlmsg_len)
     exit(1);
   n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
   if (hdr->nlmsg_type == NLMSG_DONE) {
     *reply_len = 0;
     return 0;
   }
   if (n < sizeof(struct nlmsghdr))
     exit(1);
   if (reply_len && hdr->nlmsg_type == reply_type) {
     *reply_len = n;
     return 0;
   }
   if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
     exit(1);
   if (hdr->nlmsg_type != NLMSG_ERROR)
     exit(1);
   return -((struct nlmsgerr*)(hdr + 1))->error;
}

static int netlink_send(struct nlmsg* nlmsg, int sock)
{
   return netlink_send_ext(nlmsg, sock, 0, NULL);
}

static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
                             unsigned int total_len)
{
   struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
   if (offset == total_len || offset + hdr->nlmsg_len > total_len)
     return -1;
   return hdr->nlmsg_len;
}

static void netlink_device_change(struct nlmsg* nlmsg, int sock,
                                   const char* name, bool up, const 
char* master,
                                   const void* mac, int macsize,
                                   const char* new_name)
{
   struct ifinfomsg hdr;
   memset(&hdr, 0, sizeof(hdr));
   if (up)
     hdr.ifi_flags = hdr.ifi_change = IFF_UP;
   hdr.ifi_index = if_nametoindex(name);
   netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
   if (new_name)
     netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
   if (master) {
     int ifindex = if_nametoindex(master);
     netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
   }
   if (macsize)
     netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
   int err = netlink_send(nlmsg, sock);
   (void)err;
}

const int kInitNetNsFd = 239;

#define DEVLINK_FAMILY_NAME "devlink"

#define DEVLINK_CMD_PORT_GET 5
#define DEVLINK_CMD_RELOAD 37
#define DEVLINK_ATTR_BUS_NAME 1
#define DEVLINK_ATTR_DEV_NAME 2
#define DEVLINK_ATTR_NETDEV_NAME 7
#define DEVLINK_ATTR_NETNS_FD 138

static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
{
   struct genlmsghdr genlhdr;
   struct nlattr* attr;
   int err, n;
   uint16_t id = 0;
   memset(&genlhdr, 0, sizeof(genlhdr));
   genlhdr.cmd = CTRL_CMD_GETFAMILY;
   netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
   netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
                strlen(DEVLINK_FAMILY_NAME) + 1);
   err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
   if (err) {
     return -1;
   }
   attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
                           NLMSG_ALIGN(sizeof(genlhdr)));
   for (; (char*)attr < nlmsg->buf + n;
        attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
     if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
       id = *(uint16_t*)(attr + 1);
       break;
     }
   }
   if (!id) {
     return -1;
   }
   recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
   return id;
}

static void netlink_devlink_netns_move(const char* bus_name,
                                        const char* dev_name, int netns_fd)
{
   struct genlmsghdr genlhdr;
   int sock;
   int id, err;
   sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
   if (sock == -1)
     exit(1);
   id = netlink_devlink_id_get(&nlmsg, sock);
   if (id == -1)
     goto error;
   memset(&genlhdr, 0, sizeof(genlhdr));
   genlhdr.cmd = DEVLINK_CMD_RELOAD;
   netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
   netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, 
strlen(bus_name) + 1);
   netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, 
strlen(dev_name) + 1);
   netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
   err = netlink_send(&nlmsg, sock);
   if (err) {
   }
error:
   close(sock);
}

static struct nlmsg nlmsg2;

static void initialize_devlink_ports(const char* bus_name, const char* 
dev_name,
                                      const char* netdev_prefix)
{
   struct genlmsghdr genlhdr;
   int len, total_len, id, err, offset;
   uint16_t netdev_index;
   int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
   if (sock == -1)
     exit(1);
   int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
   if (rtsock == -1)
     exit(1);
   id = netlink_devlink_id_get(&nlmsg, sock);
   if (id == -1)
     goto error;
   memset(&genlhdr, 0, sizeof(genlhdr));
   genlhdr.cmd = DEVLINK_CMD_PORT_GET;
   netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
   netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, 
strlen(bus_name) + 1);
   netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, 
strlen(dev_name) + 1);
   err = netlink_send_ext(&nlmsg, sock, id, &total_len);
   if (err) {
     goto error;
   }
   offset = 0;
   netdev_index = 0;
   while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
     struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + 
NLMSG_HDRLEN +
                                            NLMSG_ALIGN(sizeof(genlhdr)));
     for (; (char*)attr < nlmsg.buf + offset + len;
          attr = (struct nlattr*)((char*)attr + 
NLMSG_ALIGN(attr->nla_len))) {
       if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
         char* port_name;
         char netdev_name[IFNAMSIZ];
         port_name = (char*)(attr + 1);
         snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
                  netdev_index);
         netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
                               netdev_name);
         break;
       }
     }
     offset += len;
     netdev_index++;
   }
error:
   close(rtsock);
   close(sock);
}

static void initialize_devlink_pci(void)
{
   int netns = open("/proc/self/ns/net", O_RDONLY);
   if (netns == -1)
     exit(1);
   int ret = setns(kInitNetNsFd, 0);
   if (ret == -1)
     exit(1);
   netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
   ret = setns(netns, 0);
   if (ret == -1)
     exit(1);
   close(netns);
   initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
}

uint64_t r[1] = {0xffffffffffffffff};

int main(void)
{
   syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
   intptr_t res = 0;
   res = syscall(__NR_socket, 0xaul, 0x80000000000001ul, 0x84ul);
   if (res != -1)
     r[0] = res;
   *(uint32_t*)0x20444ff8 = 0;
   *(uint32_t*)0x20444ffc = 7;
   syscall(__NR_setsockopt, r[0], 0x84ul, 0x76ul, 0x20444ff8ul, 8ul);
   *(uint16_t*)0x20cf6fe4 = 0xa;
   *(uint16_t*)0x20cf6fe6 = htobe16(0x4e23);
   *(uint32_t*)0x20cf6fe8 = htobe32(0);
   *(uint64_t*)0x20cf6fec = htobe64(0);
   *(uint64_t*)0x20cf6ff4 = htobe64(1);
   *(uint32_t*)0x20cf6ffc = 0;
   syscall(__NR_setsockopt, r[0], 0x84ul, 0x64ul, 0x20cf6fe4ul, 0x1cul);
   *(uint32_t*)0x20107ff8 = 0;
   *(uint32_t*)0x20107ffc = 0x10040000;
   syscall(__NR_setsockopt, r[0], 0x84ul, 0x75ul, 0x20107ff8ul, 8ul);
   *(uint16_t*)0x208c0000 = 0xa;
   *(uint16_t*)0x208c0002 = htobe16(0x4e23);
   *(uint32_t*)0x208c0004 = htobe32(0);
   *(uint64_t*)0x208c0008 = htobe64(0);
   *(uint64_t*)0x208c0010 = htobe64(1);
   *(uint32_t*)0x208c0018 = 0;
   syscall(__NR_connect, r[0], 0x208c0000ul, 0x1cul);
   *(uint32_t*)0x2081e000 = 0;
   *(uint16_t*)0x2081e004 = 0x3b;
   *(uint16_t*)0x2081e006 = 0x29;
   *(uint16_t*)0x2081e008 = 0;
   syscall(__NR_setsockopt, r[0], 0x84ul, 0x77ul, 0x2081e000ul, 0x2deul);
   return 0;
}



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-10-20 15:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-18 21:29 syzkaller test panic: Linux 5.4.y john.p.donnelly
2021-10-19 15:24 ` mleitner
2021-10-19 20:05   ` john.p.donnelly
2021-10-19 21:35     ` Marcelo Ricardo Leitner
2021-10-19 21:41       ` john.p.donnelly
2021-10-20 15:12       ` john.p.donnelly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).