Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <arpa/inet.h>
- #include <endian.h>
- #include <errno.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 <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[4096];
- };
- 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;
- if (size > 0)
- 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, bool dofail)
- {
- 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;
- ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
- (struct sockaddr*)&addr, sizeof(addr));
- if (n != (ssize_t)hdr->nlmsg_len) {
- if (dofail)
- exit(1);
- return -1;
- }
- n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
- if (reply_len)
- *reply_len = 0;
- if (n < 0) {
- if (dofail)
- exit(1);
- return -1;
- }
- if (n < (ssize_t)sizeof(struct nlmsghdr)) {
- errno = EINVAL;
- if (dofail)
- exit(1);
- return -1;
- }
- if (hdr->nlmsg_type == NLMSG_DONE)
- return 0;
- if (reply_len && hdr->nlmsg_type == reply_type) {
- *reply_len = n;
- return 0;
- }
- if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
- errno = EINVAL;
- if (dofail)
- exit(1);
- return -1;
- }
- if (hdr->nlmsg_type != NLMSG_ERROR) {
- errno = EINVAL;
- if (dofail)
- exit(1);
- return -1;
- }
- errno = -((struct nlmsgerr*)(hdr + 1))->error;
- return -errno;
- }
- static int netlink_query_family_id(struct nlmsg* nlmsg, int sock,
- const char* family_name, bool dofail)
- {
- struct genlmsghdr genlhdr;
- 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, family_name,
- strnlen(family_name, GENL_NAMSIZ - 1) + 1);
- int n = 0;
- int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
- if (err < 0) {
- return -1;
- }
- uint16_t id = 0;
- struct nlattr* 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) {
- errno = EINVAL;
- return -1;
- }
- recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
- return id;
- }
- const int kInitNetNsFd = 201;
- static long syz_init_net_socket(volatile long domain, volatile long type,
- volatile long proto)
- {
- return syscall(__NR_socket, domain, type, proto);
- }
- static long syz_genetlink_get_family_id(volatile long name,
- volatile long sock_arg)
- {
- int fd = sock_arg;
- if (fd < 0) {
- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
- if (fd == -1) {
- return -1;
- }
- }
- struct nlmsg nlmsg_tmp;
- int ret = netlink_query_family_id(&nlmsg_tmp, fd, (char*)name, false);
- if ((int)sock_arg < 0)
- close(fd);
- if (ret < 0) {
- return -1;
- }
- return ret;
- }
- uint64_t r[2] = {0xffffffffffffffff, 0x0};
- int main(void)
- {
- syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul,
- /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
- /*offset=*/0ul);
- syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
- /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
- /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
- /*offset=*/0ul);
- syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
- /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
- /*offset=*/0ul);
- intptr_t res = 0;
- res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x10);
- if (res != -1)
- r[0] = res;
- syz_genetlink_get_family_id(/*name=*/0, /*fd=*/-1);
- syz_init_net_socket(/*domain=*/0x10, /*type=*/3, /*proto=*/0x10);
- memcpy((void*)0x20000340, "nbd\000", 4);
- syz_genetlink_get_family_id(/*name=*/0x20000340, /*fd=*/-1);
- memcpy((void*)0x20000040, "batadv\000", 7);
- res = -1;
- res = syz_genetlink_get_family_id(/*name=*/0x20000040, /*fd=*/r[0]);
- if (res != -1)
- r[1] = res;
- *(uint64_t*)0x20000140 = 0x20000000;
- *(uint16_t*)0x20000000 = 0x10;
- *(uint16_t*)0x20000002 = 0;
- *(uint32_t*)0x20000004 = 0;
- *(uint32_t*)0x20000008 = 0x1000000;
- *(uint32_t*)0x20000148 = 0xc;
- *(uint64_t*)0x20000150 = 0x20000100;
- *(uint64_t*)0x20000100 = 0x20000080;
- *(uint32_t*)0x20000080 = 0x5c;
- *(uint16_t*)0x20000084 = r[1];
- *(uint16_t*)0x20000086 = 0x10;
- *(uint32_t*)0x20000088 = 0x70bd2b;
- *(uint32_t*)0x2000008c = 0x25dfdbff;
- *(uint8_t*)0x20000090 = 0xa;
- *(uint8_t*)0x20000091 = 0;
- *(uint16_t*)0x20000092 = 0;
- *(uint16_t*)0x20000094 = 5;
- *(uint16_t*)0x20000096 = 0x29;
- *(uint8_t*)0x20000098 = 0;
- *(uint16_t*)0x2000009c = 8;
- *(uint16_t*)0x2000009e = 0xb;
- *(uint32_t*)0x200000a0 = 0xfffffff8;
- *(uint16_t*)0x200000a4 = 5;
- *(uint16_t*)0x200000a6 = 0x38;
- *(uint8_t*)0x200000a8 = 0;
- *(uint16_t*)0x200000ac = 5;
- *(uint16_t*)0x200000ae = 0x2d;
- *(uint8_t*)0x200000b0 = 1;
- *(uint16_t*)0x200000b4 = 8;
- *(uint16_t*)0x200000b6 = 0x31;
- *(uint32_t*)0x200000b8 = 4;
- *(uint16_t*)0x200000bc = 5;
- *(uint16_t*)0x200000be = 0x2a;
- *(uint8_t*)0x200000c0 = 0;
- *(uint16_t*)0x200000c4 = 8;
- *(uint16_t*)0x200000c6 = 0x34;
- *(uint32_t*)0x200000c8 = 4;
- *(uint16_t*)0x200000cc = 5;
- *(uint16_t*)0x200000ce = 0x2e;
- *(uint8_t*)0x200000d0 = 1;
- *(uint16_t*)0x200000d4 = 5;
- *(uint16_t*)0x200000d6 = 0x2f;
- *(uint8_t*)0x200000d8 = 0;
- *(uint64_t*)0x20000108 = 0x5c;
- *(uint64_t*)0x20000158 = 1;
- *(uint64_t*)0x20000160 = 0;
- *(uint64_t*)0x20000168 = 0;
- *(uint32_t*)0x20000170 = 0x4040010;
- syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0x20000140ul, /*f=MSG_OOB*/ 1ul);
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);
- syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0ul,
- /*f=MSG_PROBE|MSG_DONTWAIT*/ 0x50ul);
- syscall(__NR_socketpair, /*domain=AF_VSOCK*/ 0x28ul, /*type=*/0ul,
- /*proto=*/0, /*fds=*/0ul);
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);
- *(uint64_t*)0x20001880 = 0;
- *(uint32_t*)0x20001888 = 0;
- *(uint64_t*)0x20001890 = 0;
- *(uint64_t*)0x20001898 = 1;
- *(uint64_t*)0x200018a0 = 0;
- *(uint64_t*)0x200018a8 = 0;
- *(uint32_t*)0x200018b0 = 0;
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0x20001880ul,
- /*f=MSG_BATCH|MSG_CONFIRM*/ 0x40800ul);
- syscall(__NR_ioctl, /*fd=*/-1, /*cmd=*/0x5411, /*arg=*/0ul);
- syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul,
- /*f=MSG_FASTOPEN|MSG_DONTROUTE|0x40000000*/ 0x60000004ul);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment