// https://syzkaller.appspot.com/bug?id=2d2b235cd0713f8368d32ae05fb315eeab2215d1 // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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; 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 137 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; 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)); netlink_send(&nlmsg, sock); 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"); } #ifndef __NR_bpf #define __NR_bpf 321 #endif uint64_t r[1] = {0xffffffffffffffff}; int main(void) { syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0); intptr_t res = 0; *(uint32_t*)0x20000200 = 0xc; *(uint32_t*)0x20000204 = 0xe; *(uint64_t*)0x20000208 = 0x20000b00; memcpy( (void*)0x20000b00, "\xb7\x02\x00\x00\x14\x00\x00\x00\xbf\xa3\x00\x00\x00\x00\x00\x00\x07\x01" "\x00\x00\x00\xfe\xff\xff\x7a\x0a\xf0\xff\xf8\xff\xff\xff\x79\xa4\xf0\xff" "\x00\x00\x00\x00\xb7\x06\x00\x00\xff\xff\xff\xff\x2d\x64\x05\x00\x00\x00" "\x00\x00\x65\x04\x04\x00\x01\x00\x00\x00\x04\x04\x00\x00\x01\x00\x7d\x60" "\xb7\x03\x00\x00\x00\x00\x00\x00\x6a\x0a\x00\xfe\x00\x00\x00\x00\x85\x00" "\x00\x00\x0d\x00\x00\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00" "\x00\x00\x00\x00\xe3\xa3\x33\xa0\xda\xf2\xf7\x34\x51\xc0\xe1\x01\x00\x00" "\x00\x68\xcb\x7d\x18\xad\x18\x18\x67\x51\x4f\xe6\x00\x77\xd4\xdd\x90\x12" "\x3d\x27\xe7\xcf\x43\x54\x8e\xe8\x58\x57\xad\x4a\x77\xcb\x56\xe0\x7d\xfb" "\xdf\xd4\xe7\x54\x77\x0e\xc6\x77\xd6\xac\x14\xc2\xc7\x94\xf7\x2c\xbf\x5f" "\xe3\x17\x89\xe7\x02\x33\xbf\xd8\x11\x5e\xfd\x90\xc8\xc4\x82\x58\xf8\xdb" "\xe8\x2e\x16\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x79\x0a\xe2\xfd\x45\xd5" "\x4b\x10\x7c\x8c\x24\x7f\x19\x5e\x32\xf1\x77\x99\xd6\x70\x74\x32\xff\x48" "\xbc\x08\x57\x63\x31\x41\x66\x44\x3c\xe7\x2c\x74\xf3\xdb\x89\x0e\x1f\xf1" "\x5a\x10\xd9\x1f\x67\xe9\xa2\x32\xfe\x22\x38\xff\xf8\x67\xba\x8f\xd4\x1b" "\x29\xca\xad\x2a\x98\x6e\x0e\x24\x4b\xd1\x17\x25\x2e\x47\xff\xda\x1a\x86" "\x9d\xb7\xe6\x32\xdf\x4d\xe8\x57\x23\x44\xb4\x19\xc4\x5c\x21\x70\xfe\x87" "\x36\x92\xd8\x25\x51\x70\xc1\x68\x22\xbd\xff\xd3\x07\x00\x00\x00\x00\x00" "\x00\x00\xbd\xef\x00\x00\x00\x00\xd8\xfd\x8c\x6e\x62\xd0\x96\x7a\xb7\xe4" "\x36\x86\xb4\xd1\xe0\x3e\x32\x6b\xee\xa7\x90\x5e\xf7\xde\x37\x5e\xf8\xbc" "\x81\x43\xdf\x20\xd1\x3c\x37\xdb\x26\x99\xf1\x21\x0f\xab\x70\x71\xcc\x30" "\x94\x07\x8a\x04\x47\x77\xaa\xb9\xd8\x6c\xf5\x0a\xfe\xfd\x7b\xd5\x0b\x22" "\xbd\x24\x91\x33\x18\x18\xa1\x0f\x2a\xc8\xc3\x24\x95\x82\xa2\x0d\x4e\x04" "\xfd\x1a\xb7\x88\x3f\x65\x6e\x84\x13\x7d\x5f\x7a\x6e\xdb\xa8\x6a\x7b\x9a" "\x4c\x2f\x3b\x3a\x8a\xbf\x93\xb2\x80\xea\x53\xce\x01\xdc\xc2\xd3\x0f\x43" "\x10\xe8\x28\x1b\x0c\xdc\x01\x7f\x97\x59\x06\x0e\xa8\x8a\x40\x65\x97\xe9" "\x66\xa8\x5c\x9a\x74\xca\x19\x67\x00\x21\x8f\x91\x97\xe7\xa5\x51\x3c\x13" "\xe7\x9d\x46\xbb\x4b\x84\xc1\x6f\xd5\x6e\xe4\x50\xe4\x11\xd7\x5a\x59\x9f" "\xa3\xde\x81\x12\x61\x47\xb7\x61\x3b\x64\x4b\xa7\x58\x0b\x2a\x41\x00\x00" "\x00\x00\x00\x00\x00\xee\xd1\xc8\x92\x42\x2f\x54\xd5\xa2\xe1\xcf\x1a\x60" "\xfe\x2d\xcc\x1a\x46\x5a\xa8\xd5\x4c\xb4\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x7e\xbb\xd0\x63\x73\x92\x30\xf7\xbb\xe8\x92\xa2\xa4\x73\x2c\x58\xb3" "\x7c\xb8\x4e\x61\x60\xfd\xfa\x34\x1c\x7c\xa2\x93\xbd\xec\x78\x3d\xaa\xf3" "\x0e\x06\x6b\xa1\x80\x66\xd6\xe2\x30\x03\xd1\xc6\xdb\x50\x6b\xa4\xeb\xe8" "\x2b\x77\x4d\x1f\xe7\xa1\x29\xa9\xcf\x59\x7e\xac\x01\x9a\x91\xe1\xd7\xf1" "\x84\xbe\x70\xf1\x59\x5a\xf1\x5b\xb4\x13\xdc\xd2\x85\x20\xb7\x42\x5d\xd3" "\x73\x3a\x0e\x35\xdd\x2a\xcd\x50\x80\x94\xe1\xa1\xa2\x29\xb9\x1d\xc2\xa8" "\xea\x87\xa4\xef\x6d\x1f\x84\x9f\x4d\xa8\x89\xd1\xfc\xdd\x07\x9e\xa5\x25" "\x5b\x9d\x1f\xaf\x1a\x43\xac\x20\x05\xa3\x3a\x89\xcf\xe2\xde\x2e\xa7\x81" "\xcd\x39\x2c\xfe\x97\xbf\x6c\xc9\x17\xd4\x80\x7b\xff\x8c\xb3\x2a\xd4\x5b" "\x89\x6a\x68\x98\x46\xb4\x86\x7f\x0a\xca\x66\xf5\xab\x34\x94\xba\xf5\xdd" "\xc2\xdb\xfe\x36\x2c\xcf\x8b\x04\x90\x87\x08\xcf\x68\x79\xe6\x8b\xf2\x51" "\x27\xd5\xc3\xda\xcf\x9a\xd9\x9c\xf2\xbb\x9b\xa9\x32\x7c\xb8\xb6\xfa\xc2" "\xa2\x6a\xd2\x89\xef\x5a\x17\x42\xa4\xc2\x8e\xed\xdb\x8a\x47\xc5\x5a\x15" "\x90\x7b", 812); *(uint64_t*)0x20000210 = 0x20000340; memcpy((void*)0x20000340, "syzkaller\000", 10); *(uint32_t*)0x20000218 = 0; *(uint32_t*)0x2000021c = 0; *(uint64_t*)0x20000220 = 0; *(uint32_t*)0x20000228 = 0; *(uint32_t*)0x2000022c = 0; *(uint8_t*)0x20000230 = 0; *(uint8_t*)0x20000231 = 0; *(uint8_t*)0x20000232 = 0; *(uint8_t*)0x20000233 = 0; *(uint8_t*)0x20000234 = 0; *(uint8_t*)0x20000235 = 0; *(uint8_t*)0x20000236 = 0; *(uint8_t*)0x20000237 = 0; *(uint8_t*)0x20000238 = 0; *(uint8_t*)0x20000239 = 0; *(uint8_t*)0x2000023a = 0; *(uint8_t*)0x2000023b = 0; *(uint8_t*)0x2000023c = 0; *(uint8_t*)0x2000023d = 0; *(uint8_t*)0x2000023e = 0; *(uint8_t*)0x2000023f = 0; *(uint32_t*)0x20000240 = 0; *(uint32_t*)0x20000244 = 0; *(uint32_t*)0x20000248 = -1; *(uint32_t*)0x2000024c = 8; *(uint64_t*)0x20000250 = 0x20000000; *(uint32_t*)0x20000000 = 0; *(uint32_t*)0x20000004 = 0; *(uint32_t*)0x20000258 = 0x24f; *(uint32_t*)0x2000025c = 0x10; *(uint64_t*)0x20000260 = 0x20000000; *(uint32_t*)0x20000000 = 0; *(uint32_t*)0x20000004 = 0; *(uint32_t*)0x20000008 = 0; *(uint32_t*)0x2000000c = 0; *(uint32_t*)0x20000268 = 0; res = syscall(__NR_bpf, 5ul, 0x20000200ul, 0x48ul); if (res != -1) r[0] = res; *(uint32_t*)0x200004c0 = r[0]; *(uint32_t*)0x200004c4 = 0x60; *(uint32_t*)0x200004c8 = 0x9b2; *(uint32_t*)0x200004cc = 0x1000000; *(uint64_t*)0x200004d0 = 0x20000100; memcpy((void*)0x20000100, "\x00\x00\x00\x3f\x00\x00\x00\x7e\x5b\xc5\x79\x5e" "\xca\xa2\x9a\x16\xf2\x91\xd3\x6a\x48\xe9\x31\x00" "\xff\xff\x81", 27); *(uint64_t*)0x200004d8 = 0; *(uint32_t*)0x200004e0 = 0x100; *(uint32_t*)0x200004e4 = 0xf2ffffff; *(uint32_t*)0x200004e8 = 0xfffffe94; *(uint32_t*)0x200004ec = 0x3e0; *(uint64_t*)0x200004f0 = 0x20000000; *(uint64_t*)0x200004f8 = 0x20000140; syscall(__NR_bpf, 0xaul, 0x200004c0ul, 0x28ul); return 0; }