Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // autogenerated by syzkaller (https://github.com/google/syzkaller)
- #define _GNU_SOURCE
- #include <arpa/inet.h>
- #include <dirent.h>
- #include <endian.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <net/if.h>
- #include <net/if_arp.h>
- #include <netinet/in.h>
- #include <pthread.h>
- #include <sched.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <sys/mman.h>
- #include <sys/mount.h>
- #include <sys/prctl.h>
- #include <sys/resource.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/uio.h>
- #include <sys/wait.h>
- #include <time.h>
- #include <unistd.h>
- #include <linux/capability.h>
- #include <linux/futex.h>
- #include <linux/genetlink.h>
- #include <linux/if_addr.h>
- #include <linux/if_ether.h>
- #include <linux/if_link.h>
- #include <linux/if_tun.h>
- #include <linux/in6.h>
- #include <linux/ip.h>
- #include <linux/loop.h>
- #include <linux/neighbour.h>
- #include <linux/net.h>
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <linux/tcp.h>
- #include <linux/veth.h>
- #ifndef __NR_memfd_create
- #define __NR_memfd_create 319
- #endif
- static unsigned long long procid;
- static __thread int clone_ongoing;
- static __thread int skip_segv;
- static __thread jmp_buf segv_env;
- static void segv_handler(int sig, siginfo_t* info, void* ctx)
- {
- if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
- exit(sig);
- }
- uintptr_t addr = (uintptr_t)info->si_addr;
- const uintptr_t prog_start = 1 << 20;
- const uintptr_t prog_end = 100 << 20;
- int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
- int valid = addr < prog_start || addr > prog_end;
- if (skip && valid) {
- _longjmp(segv_env, 1);
- }
- exit(sig);
- }
- static void install_segv_handler(void)
- {
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = SIG_IGN;
- syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
- syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
- memset(&sa, 0, sizeof(sa));
- sa.sa_sigaction = segv_handler;
- sa.sa_flags = SA_NODEFER | SA_SIGINFO;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGBUS, &sa, NULL);
- }
- #define NONFAILING(...) \
- ({ \
- int ok = 1; \
- __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
- if (_setjmp(segv_env) == 0) { \
- __VA_ARGS__; \
- } else \
- ok = 0; \
- __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
- ok; \
- })
- static void sleep_ms(uint64_t ms)
- {
- usleep(ms * 1000);
- }
- static uint64_t current_time_ms(void)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts))
- exit(1);
- return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
- }
- static void use_temporary_dir(void)
- {
- char tmpdir_template[] = "./syzkaller.XXXXXX";
- char* tmpdir = mkdtemp(tmpdir_template);
- if (!tmpdir)
- exit(1);
- if (chmod(tmpdir, 0777))
- exit(1);
- if (chdir(tmpdir))
- exit(1);
- }
- static void thread_start(void* (*fn)(void*), void* arg)
- {
- pthread_t th;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, 128 << 10);
- int i = 0;
- for (; i < 100; i++) {
- if (pthread_create(&th, &attr, fn, arg) == 0) {
- pthread_attr_destroy(&attr);
- return;
- }
- if (errno == EAGAIN) {
- usleep(50);
- continue;
- }
- break;
- }
- exit(1);
- }
- typedef struct {
- int state;
- } event_t;
- static void event_init(event_t* ev)
- {
- ev->state = 0;
- }
- static void event_reset(event_t* ev)
- {
- ev->state = 0;
- }
- static void event_set(event_t* ev)
- {
- if (ev->state)
- exit(1);
- __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
- syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
- }
- static void event_wait(event_t* ev)
- {
- while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
- syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
- }
- static int event_isset(event_t* ev)
- {
- return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
- }
- static int event_timedwait(event_t* ev, uint64_t timeout)
- {
- uint64_t start = current_time_ms();
- uint64_t now = start;
- for (;;) {
- uint64_t remain = timeout - (now - start);
- struct timespec ts;
- ts.tv_sec = remain / 1000;
- ts.tv_nsec = (remain % 1000) * 1000 * 1000;
- syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
- if (__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
- return 1;
- now = current_time_ms();
- if (now - start > timeout)
- return 0;
- }
- }
- static bool write_file(const char* file, const char* what, ...)
- {
- char buf[1024];
- va_list args;
- va_start(args, what);
- vsnprintf(buf, sizeof(buf), what, args);
- va_end(args);
- buf[sizeof(buf) - 1] = 0;
- int len = strlen(buf);
- int fd = open(file, O_WRONLY | O_CLOEXEC);
- if (fd == -1)
- return false;
- if (write(fd, buf, len) != len) {
- int err = errno;
- close(fd);
- errno = err;
- return false;
- }
- close(fd);
- return true;
- }
- 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 void netlink_nest(struct nlmsg* nlmsg, int typ)
- {
- struct nlattr* attr = (struct nlattr*)nlmsg->pos;
- attr->nla_type = typ;
- nlmsg->pos += sizeof(*attr);
- nlmsg->nested[nlmsg->nesting++] = attr;
- }
- static void netlink_done(struct nlmsg* nlmsg)
- {
- struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
- attr->nla_len = nlmsg->pos - (char*)attr;
- }
- 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_send(struct nlmsg* nlmsg, int sock)
- {
- return netlink_send_ext(nlmsg, sock, 0, NULL, true);
- }
- 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;
- }
- 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_add_device_impl(struct nlmsg* nlmsg, const char* type,
- const char* name, bool up)
- {
- struct ifinfomsg hdr;
- memset(&hdr, 0, sizeof(hdr));
- if (up)
- hdr.ifi_flags = hdr.ifi_change = IFF_UP;
- netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
- sizeof(hdr));
- if (name)
- netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
- netlink_nest(nlmsg, IFLA_LINKINFO);
- netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
- }
- static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
- const char* name)
- {
- netlink_add_device_impl(nlmsg, type, name, false);
- netlink_done(nlmsg);
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
- const char* peer)
- {
- netlink_add_device_impl(nlmsg, "veth", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- netlink_nest(nlmsg, VETH_INFO_PEER);
- nlmsg->pos += sizeof(struct ifinfomsg);
- netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_xfrm(struct nlmsg* nlmsg, int sock, const char* name)
- {
- netlink_add_device_impl(nlmsg, "xfrm", name, true);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- int if_id = 1;
- netlink_attr(nlmsg, 2, &if_id, sizeof(if_id));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
- const char* slave1, const char* slave2)
- {
- netlink_add_device_impl(nlmsg, "hsr", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- int ifindex1 = if_nametoindex(slave1);
- netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
- int ifindex2 = if_nametoindex(slave2);
- netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_linked(struct nlmsg* nlmsg, int sock, const char* type,
- const char* name, const char* link)
- {
- netlink_add_device_impl(nlmsg, type, name, false);
- netlink_done(nlmsg);
- int ifindex = if_nametoindex(link);
- netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name,
- const char* link, uint16_t id, uint16_t proto)
- {
- netlink_add_device_impl(nlmsg, "vlan", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id));
- netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int ifindex = if_nametoindex(link);
- netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name,
- const char* link)
- {
- netlink_add_device_impl(nlmsg, "macvlan", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- uint32_t mode = MACVLAN_MODE_BRIDGE;
- netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int ifindex = if_nametoindex(link);
- netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- static void netlink_add_geneve(struct nlmsg* nlmsg, int sock, const char* name,
- uint32_t vni, struct in_addr* addr4,
- struct in6_addr* addr6)
- {
- netlink_add_device_impl(nlmsg, "geneve", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- netlink_attr(nlmsg, IFLA_GENEVE_ID, &vni, sizeof(vni));
- if (addr4)
- netlink_attr(nlmsg, IFLA_GENEVE_REMOTE, addr4, sizeof(*addr4));
- if (addr6)
- netlink_attr(nlmsg, IFLA_GENEVE_REMOTE6, addr6, sizeof(*addr6));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- #define IFLA_IPVLAN_FLAGS 2
- #define IPVLAN_MODE_L3S 2
- #undef IPVLAN_F_VEPA
- #define IPVLAN_F_VEPA 2
- static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name,
- const char* link, uint16_t mode, uint16_t flags)
- {
- netlink_add_device_impl(nlmsg, "ipvlan", name, false);
- netlink_nest(nlmsg, IFLA_INFO_DATA);
- netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode));
- netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags));
- netlink_done(nlmsg);
- netlink_done(nlmsg);
- int ifindex = if_nametoindex(link);
- netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
- int err = netlink_send(nlmsg, sock);
- if (err < 0) {
- }
- }
- 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);
- if (err < 0) {
- }
- }
- static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
- const void* addr, int addrsize)
- {
- struct ifaddrmsg hdr;
- memset(&hdr, 0, sizeof(hdr));
- hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
- hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
- hdr.ifa_scope = RT_SCOPE_UNIVERSE;
- hdr.ifa_index = if_nametoindex(dev);
- netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
- sizeof(hdr));
- netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
- netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
- return netlink_send(nlmsg, sock);
- }
- static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
- const char* addr)
- {
- struct in_addr in_addr;
- inet_pton(AF_INET, addr, &in_addr);
- int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
- if (err < 0) {
- }
- }
- static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
- const char* addr)
- {
- struct in6_addr in6_addr;
- inet_pton(AF_INET6, addr, &in6_addr);
- int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
- if (err < 0) {
- }
- }
- static struct nlmsg nlmsg;
- #define DEVLINK_FAMILY_NAME "devlink"
- #define DEVLINK_CMD_PORT_GET 5
- #define DEVLINK_ATTR_BUS_NAME 1
- #define DEVLINK_ATTR_DEV_NAME 2
- #define DEVLINK_ATTR_NETDEV_NAME 7
- 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_query_family_id(&nlmsg, sock, DEVLINK_FAMILY_NAME, true);
- 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, true);
- if (err < 0) {
- 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);
- }
- #define DEV_IPV4 "172.20.20.%d"
- #define DEV_IPV6 "fe80::%02x"
- #define DEV_MAC 0x00aaaaaaaaaa
- static void netdevsim_add(unsigned int addr, unsigned int port_count)
- {
- write_file("/sys/bus/netdevsim/del_device", "%u", addr);
- if (write_file("/sys/bus/netdevsim/new_device", "%u %u", addr, port_count)) {
- char buf[32];
- snprintf(buf, sizeof(buf), "netdevsim%d", addr);
- initialize_devlink_ports("netdevsim", buf, "netdevsim");
- }
- }
- #define WG_GENL_NAME "wireguard"
- enum wg_cmd {
- WG_CMD_GET_DEVICE,
- WG_CMD_SET_DEVICE,
- };
- enum wgdevice_attribute {
- WGDEVICE_A_UNSPEC,
- WGDEVICE_A_IFINDEX,
- WGDEVICE_A_IFNAME,
- WGDEVICE_A_PRIVATE_KEY,
- WGDEVICE_A_PUBLIC_KEY,
- WGDEVICE_A_FLAGS,
- WGDEVICE_A_LISTEN_PORT,
- WGDEVICE_A_FWMARK,
- WGDEVICE_A_PEERS,
- };
- enum wgpeer_attribute {
- WGPEER_A_UNSPEC,
- WGPEER_A_PUBLIC_KEY,
- WGPEER_A_PRESHARED_KEY,
- WGPEER_A_FLAGS,
- WGPEER_A_ENDPOINT,
- WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- WGPEER_A_LAST_HANDSHAKE_TIME,
- WGPEER_A_RX_BYTES,
- WGPEER_A_TX_BYTES,
- WGPEER_A_ALLOWEDIPS,
- WGPEER_A_PROTOCOL_VERSION,
- };
- enum wgallowedip_attribute {
- WGALLOWEDIP_A_UNSPEC,
- WGALLOWEDIP_A_FAMILY,
- WGALLOWEDIP_A_IPADDR,
- WGALLOWEDIP_A_CIDR_MASK,
- };
- static void netlink_wireguard_setup(void)
- {
- const char ifname_a[] = "wg0";
- const char ifname_b[] = "wg1";
- const char ifname_c[] = "wg2";
- const char private_a[] =
- "\xa0\x5c\xa8\x4f\x6c\x9c\x8e\x38\x53\xe2\xfd\x7a\x70\xae\x0f\xb2\x0f\xa1"
- "\x52\x60\x0c\xb0\x08\x45\x17\x4f\x08\x07\x6f\x8d\x78\x43";
- const char private_b[] =
- "\xb0\x80\x73\xe8\xd4\x4e\x91\xe3\xda\x92\x2c\x22\x43\x82\x44\xbb\x88\x5c"
- "\x69\xe2\x69\xc8\xe9\xd8\x35\xb1\x14\x29\x3a\x4d\xdc\x6e";
- const char private_c[] =
- "\xa0\xcb\x87\x9a\x47\xf5\xbc\x64\x4c\x0e\x69\x3f\xa6\xd0\x31\xc7\x4a\x15"
- "\x53\xb6\xe9\x01\xb9\xff\x2f\x51\x8c\x78\x04\x2f\xb5\x42";
- const char public_a[] =
- "\x97\x5c\x9d\x81\xc9\x83\xc8\x20\x9e\xe7\x81\x25\x4b\x89\x9f\x8e\xd9\x25"
- "\xae\x9f\x09\x23\xc2\x3c\x62\xf5\x3c\x57\xcd\xbf\x69\x1c";
- const char public_b[] =
- "\xd1\x73\x28\x99\xf6\x11\xcd\x89\x94\x03\x4d\x7f\x41\x3d\xc9\x57\x63\x0e"
- "\x54\x93\xc2\x85\xac\xa4\x00\x65\xcb\x63\x11\xbe\x69\x6b";
- const char public_c[] =
- "\xf4\x4d\xa3\x67\xa8\x8e\xe6\x56\x4f\x02\x02\x11\x45\x67\x27\x08\x2f\x5c"
- "\xeb\xee\x8b\x1b\xf5\xeb\x73\x37\x34\x1b\x45\x9b\x39\x22";
- const uint16_t listen_a = 20001;
- const uint16_t listen_b = 20002;
- const uint16_t listen_c = 20003;
- const uint16_t af_inet = AF_INET;
- const uint16_t af_inet6 = AF_INET6;
- const struct sockaddr_in endpoint_b_v4 = {
- .sin_family = AF_INET,
- .sin_port = htons(listen_b),
- .sin_addr = {htonl(INADDR_LOOPBACK)}};
- const struct sockaddr_in endpoint_c_v4 = {
- .sin_family = AF_INET,
- .sin_port = htons(listen_c),
- .sin_addr = {htonl(INADDR_LOOPBACK)}};
- struct sockaddr_in6 endpoint_a_v6 = {.sin6_family = AF_INET6,
- .sin6_port = htons(listen_a)};
- endpoint_a_v6.sin6_addr = in6addr_loopback;
- struct sockaddr_in6 endpoint_c_v6 = {.sin6_family = AF_INET6,
- .sin6_port = htons(listen_c)};
- endpoint_c_v6.sin6_addr = in6addr_loopback;
- const struct in_addr first_half_v4 = {0};
- const struct in_addr second_half_v4 = {(uint32_t)htonl(128 << 24)};
- const struct in6_addr first_half_v6 = {{{0}}};
- const struct in6_addr second_half_v6 = {{{0x80}}};
- const uint8_t half_cidr = 1;
- const uint16_t persistent_keepalives[] = {1, 3, 7, 9, 14, 19};
- struct genlmsghdr genlhdr = {.cmd = WG_CMD_SET_DEVICE, .version = 1};
- int sock;
- int id, err;
- sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
- if (sock == -1) {
- return;
- }
- id = netlink_query_family_id(&nlmsg, sock, WG_GENL_NAME, true);
- if (id == -1)
- goto error;
- netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
- netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_a, strlen(ifname_a) + 1);
- netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_a, 32);
- netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_a, 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
- sizeof(endpoint_b_v4));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[0], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
- sizeof(first_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
- sizeof(first_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v6,
- sizeof(endpoint_c_v6));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[1], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
- sizeof(second_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
- sizeof(second_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- err = netlink_send(&nlmsg, sock);
- if (err < 0) {
- }
- netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
- netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_b, strlen(ifname_b) + 1);
- netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_b, 32);
- netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_b, 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
- sizeof(endpoint_a_v6));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[2], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
- sizeof(first_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
- sizeof(first_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v4,
- sizeof(endpoint_c_v4));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[3], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
- sizeof(second_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
- sizeof(second_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- err = netlink_send(&nlmsg, sock);
- if (err < 0) {
- }
- netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
- netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_c, strlen(ifname_c) + 1);
- netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_c, 32);
- netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_c, 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
- sizeof(endpoint_a_v6));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[4], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
- sizeof(first_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
- sizeof(first_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
- netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
- sizeof(endpoint_b_v4));
- netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- &persistent_keepalives[5], 2);
- netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
- sizeof(second_half_v4));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_nest(&nlmsg, NLA_F_NESTED | 0);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
- netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
- sizeof(second_half_v6));
- netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- netlink_done(&nlmsg);
- err = netlink_send(&nlmsg, sock);
- if (err < 0) {
- }
- error:
- close(sock);
- }
- static void initialize_netdevices(void)
- {
- char netdevsim[16];
- sprintf(netdevsim, "netdevsim%d", (int)procid);
- struct {
- const char* type;
- const char* dev;
- } devtypes[] = {
- {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"}, {"vcan", "vcan0"},
- {"bond", "bond0"}, {"team", "team0"}, {"dummy", "dummy0"},
- {"nlmon", "nlmon0"}, {"caif", "caif0"}, {"batadv", "batadv0"},
- {"vxcan", "vxcan1"}, {"veth", 0}, {"wireguard", "wg0"},
- {"wireguard", "wg1"}, {"wireguard", "wg2"},
- };
- const char* devmasters[] = {"bridge", "bond", "team", "batadv"};
- struct {
- const char* name;
- int macsize;
- bool noipv6;
- } devices[] = {
- {"lo", ETH_ALEN},
- {"sit0", 0},
- {"bridge0", ETH_ALEN},
- {"vcan0", 0, true},
- {"tunl0", 0},
- {"gre0", 0},
- {"gretap0", ETH_ALEN},
- {"ip_vti0", 0},
- {"ip6_vti0", 0},
- {"ip6tnl0", 0},
- {"ip6gre0", 0},
- {"ip6gretap0", ETH_ALEN},
- {"erspan0", ETH_ALEN},
- {"bond0", ETH_ALEN},
- {"veth0", ETH_ALEN},
- {"veth1", ETH_ALEN},
- {"team0", ETH_ALEN},
- {"veth0_to_bridge", ETH_ALEN},
- {"veth1_to_bridge", ETH_ALEN},
- {"veth0_to_bond", ETH_ALEN},
- {"veth1_to_bond", ETH_ALEN},
- {"veth0_to_team", ETH_ALEN},
- {"veth1_to_team", ETH_ALEN},
- {"veth0_to_hsr", ETH_ALEN},
- {"veth1_to_hsr", ETH_ALEN},
- {"hsr0", 0},
- {"dummy0", ETH_ALEN},
- {"nlmon0", 0},
- {"vxcan0", 0, true},
- {"vxcan1", 0, true},
- {"caif0", ETH_ALEN},
- {"batadv0", ETH_ALEN},
- {netdevsim, ETH_ALEN},
- {"xfrm0", ETH_ALEN},
- {"veth0_virt_wifi", ETH_ALEN},
- {"veth1_virt_wifi", ETH_ALEN},
- {"virt_wifi0", ETH_ALEN},
- {"veth0_vlan", ETH_ALEN},
- {"veth1_vlan", ETH_ALEN},
- {"vlan0", ETH_ALEN},
- {"vlan1", ETH_ALEN},
- {"macvlan0", ETH_ALEN},
- {"macvlan1", ETH_ALEN},
- {"ipvlan0", ETH_ALEN},
- {"ipvlan1", ETH_ALEN},
- {"veth0_macvtap", ETH_ALEN},
- {"veth1_macvtap", ETH_ALEN},
- {"macvtap0", ETH_ALEN},
- {"macsec0", ETH_ALEN},
- {"veth0_to_batadv", ETH_ALEN},
- {"veth1_to_batadv", ETH_ALEN},
- {"batadv_slave_0", ETH_ALEN},
- {"batadv_slave_1", ETH_ALEN},
- {"geneve0", ETH_ALEN},
- {"geneve1", ETH_ALEN},
- {"wg0", 0},
- {"wg1", 0},
- {"wg2", 0},
- };
- int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (sock == -1)
- exit(1);
- unsigned i;
- for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
- netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
- for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
- char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
- sprintf(slave0, "%s_slave_0", devmasters[i]);
- sprintf(veth0, "veth0_to_%s", devmasters[i]);
- netlink_add_veth(&nlmsg, sock, slave0, veth0);
- sprintf(slave1, "%s_slave_1", devmasters[i]);
- sprintf(veth1, "veth1_to_%s", devmasters[i]);
- netlink_add_veth(&nlmsg, sock, slave1, veth1);
- sprintf(master, "%s0", devmasters[i]);
- netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
- netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
- }
- netlink_add_xfrm(&nlmsg, sock, "xfrm0");
- netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
- netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
- netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
- netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
- netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
- netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
- netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
- netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi");
- netlink_add_linked(&nlmsg, sock, "virt_wifi", "virt_wifi0",
- "veth1_virt_wifi");
- netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan");
- netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q));
- netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD));
- netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan");
- netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan");
- netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0);
- netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S,
- IPVLAN_F_VEPA);
- netlink_add_veth(&nlmsg, sock, "veth0_macvtap", "veth1_macvtap");
- netlink_add_linked(&nlmsg, sock, "macvtap", "macvtap0", "veth0_macvtap");
- netlink_add_linked(&nlmsg, sock, "macsec", "macsec0", "veth1_macvtap");
- char addr[32];
- sprintf(addr, DEV_IPV4, 14 + 10);
- struct in_addr geneve_addr4;
- if (inet_pton(AF_INET, addr, &geneve_addr4) <= 0)
- exit(1);
- struct in6_addr geneve_addr6;
- if (inet_pton(AF_INET6, "fc00::01", &geneve_addr6) <= 0)
- exit(1);
- netlink_add_geneve(&nlmsg, sock, "geneve0", 0, &geneve_addr4, 0);
- netlink_add_geneve(&nlmsg, sock, "geneve1", 1, 0, &geneve_addr6);
- netdevsim_add((int)procid, 4);
- netlink_wireguard_setup();
- for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
- char addr[32];
- sprintf(addr, DEV_IPV4, i + 10);
- netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
- if (!devices[i].noipv6) {
- sprintf(addr, DEV_IPV6, i + 10);
- netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
- }
- uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
- netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
- devices[i].macsize, NULL);
- }
- close(sock);
- }
- static void initialize_netdevices_init(void)
- {
- int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (sock == -1)
- exit(1);
- struct {
- const char* type;
- int macsize;
- bool noipv6;
- bool noup;
- } devtypes[] = {
- {"nr", 7, true},
- {"rose", 5, true, true},
- };
- unsigned i;
- for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
- char dev[32], addr[32];
- sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
- sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
- netlink_add_addr4(&nlmsg, sock, dev, addr);
- if (!devtypes[i].noipv6) {
- sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
- netlink_add_addr6(&nlmsg, sock, dev, addr);
- }
- int macsize = devtypes[i].macsize;
- uint64_t macaddr = 0xbbbbbb +
- ((unsigned long long)i << (8 * (macsize - 2))) +
- (procid << (8 * (macsize - 1)));
- netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
- macsize, NULL);
- }
- close(sock);
- }
- #define MAX_FDS 30
- //% This code is derived from puff.{c,h}, found in the zlib development. The
- //% original files come with the following copyright notice:
- //% Copyright (C) 2002-2013 Mark Adler, all rights reserved
- //% version 2.3, 21 Jan 2013
- //% This software is provided 'as-is', without any express or implied
- //% warranty. In no event will the author be held liable for any damages
- //% arising from the use of this software.
- //% Permission is granted to anyone to use this software for any purpose,
- //% including commercial applications, and to alter it and redistribute it
- //% freely, subject to the following restrictions:
- //% 1. The origin of this software must not be misrepresented; you must not
- //% claim that you wrote the original software. If you use this software
- //% in a product, an acknowledgment in the product documentation would be
- //% appreciated but is not required.
- //% 2. Altered source versions must be plainly marked as such, and must not be
- //% misrepresented as being the original software.
- //% 3. This notice may not be removed or altered from any source distribution.
- //% Mark Adler [email protected]
- //% BEGIN CODE DERIVED FROM puff.{c,h}
- #define MAXBITS 15
- #define MAXLCODES 286
- #define MAXDCODES 30
- #define MAXCODES (MAXLCODES + MAXDCODES)
- #define FIXLCODES 288
- struct puff_state {
- unsigned char* out;
- unsigned long outlen;
- unsigned long outcnt;
- const unsigned char* in;
- unsigned long inlen;
- unsigned long incnt;
- int bitbuf;
- int bitcnt;
- jmp_buf env;
- };
- static int puff_bits(struct puff_state* s, int need)
- {
- long val = s->bitbuf;
- while (s->bitcnt < need) {
- if (s->incnt == s->inlen)
- longjmp(s->env, 1);
- val |= (long)(s->in[s->incnt++]) << s->bitcnt;
- s->bitcnt += 8;
- }
- s->bitbuf = (int)(val >> need);
- s->bitcnt -= need;
- return (int)(val & ((1L << need) - 1));
- }
- static int puff_stored(struct puff_state* s)
- {
- s->bitbuf = 0;
- s->bitcnt = 0;
- if (s->incnt + 4 > s->inlen)
- return 2;
- unsigned len = s->in[s->incnt++];
- len |= s->in[s->incnt++] << 8;
- if (s->in[s->incnt++] != (~len & 0xff) ||
- s->in[s->incnt++] != ((~len >> 8) & 0xff))
- return -2;
- if (s->incnt + len > s->inlen)
- return 2;
- if (s->outcnt + len > s->outlen)
- return 1;
- for (; len--; s->outcnt++, s->incnt++) {
- if (s->in[s->incnt])
- s->out[s->outcnt] = s->in[s->incnt];
- }
- return 0;
- }
- struct puff_huffman {
- short* count;
- short* symbol;
- };
- static int puff_decode(struct puff_state* s, const struct puff_huffman* h)
- {
- int first = 0;
- int index = 0;
- int bitbuf = s->bitbuf;
- int left = s->bitcnt;
- int code = first = index = 0;
- int len = 1;
- short* next = h->count + 1;
- while (1) {
- while (left--) {
- code |= bitbuf & 1;
- bitbuf >>= 1;
- int count = *next++;
- if (code - count < first) {
- s->bitbuf = bitbuf;
- s->bitcnt = (s->bitcnt - len) & 7;
- return h->symbol[index + (code - first)];
- }
- index += count;
- first += count;
- first <<= 1;
- code <<= 1;
- len++;
- }
- left = (MAXBITS + 1) - len;
- if (left == 0)
- break;
- if (s->incnt == s->inlen)
- longjmp(s->env, 1);
- bitbuf = s->in[s->incnt++];
- if (left > 8)
- left = 8;
- }
- return -10;
- }
- static int puff_construct(struct puff_huffman* h, const short* length, int n)
- {
- int len;
- for (len = 0; len <= MAXBITS; len++)
- h->count[len] = 0;
- int symbol;
- for (symbol = 0; symbol < n; symbol++)
- (h->count[length[symbol]])++;
- if (h->count[0] == n)
- return 0;
- int left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= h->count[len];
- if (left < 0)
- return left;
- }
- short offs[MAXBITS + 1];
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + h->count[len];
- for (symbol = 0; symbol < n; symbol++)
- if (length[symbol] != 0)
- h->symbol[offs[length[symbol]]++] = symbol;
- return left;
- }
- static int puff_codes(struct puff_state* s, const struct puff_huffman* lencode,
- const struct puff_huffman* distcode)
- {
- static const short lens[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
- 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
- 67, 83, 99, 115, 131, 163, 195, 227, 258};
- static const short lext[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
- 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
- static const short dists[30] = {
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
- 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
- 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
- static const short dext[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
- 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
- 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
- int symbol;
- do {
- symbol = puff_decode(s, lencode);
- if (symbol < 0)
- return symbol;
- if (symbol < 256) {
- if (s->outcnt == s->outlen)
- return 1;
- if (symbol)
- s->out[s->outcnt] = symbol;
- s->outcnt++;
- } else if (symbol > 256) {
- symbol -= 257;
- if (symbol >= 29)
- return -10;
- int len = lens[symbol] + puff_bits(s, lext[symbol]);
- symbol = puff_decode(s, distcode);
- if (symbol < 0)
- return symbol;
- unsigned dist = dists[symbol] + puff_bits(s, dext[symbol]);
- if (dist > s->outcnt)
- return -11;
- if (s->outcnt + len > s->outlen)
- return 1;
- while (len--) {
- if (dist <= s->outcnt && s->out[s->outcnt - dist])
- s->out[s->outcnt] = s->out[s->outcnt - dist];
- s->outcnt++;
- }
- }
- } while (symbol != 256);
- return 0;
- }
- static int puff_fixed(struct puff_state* s)
- {
- static int virgin = 1;
- static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
- static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
- static struct puff_huffman lencode, distcode;
- if (virgin) {
- lencode.count = lencnt;
- lencode.symbol = lensym;
- distcode.count = distcnt;
- distcode.symbol = distsym;
- short lengths[FIXLCODES];
- int symbol;
- for (symbol = 0; symbol < 144; symbol++)
- lengths[symbol] = 8;
- for (; symbol < 256; symbol++)
- lengths[symbol] = 9;
- for (; symbol < 280; symbol++)
- lengths[symbol] = 7;
- for (; symbol < FIXLCODES; symbol++)
- lengths[symbol] = 8;
- puff_construct(&lencode, lengths, FIXLCODES);
- for (symbol = 0; symbol < MAXDCODES; symbol++)
- lengths[symbol] = 5;
- puff_construct(&distcode, lengths, MAXDCODES);
- virgin = 0;
- }
- return puff_codes(s, &lencode, &distcode);
- }
- static int puff_dynamic(struct puff_state* s)
- {
- static const short order[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
- 11, 4, 12, 3, 13, 2, 14, 1, 15};
- int nlen = puff_bits(s, 5) + 257;
- int ndist = puff_bits(s, 5) + 1;
- int ncode = puff_bits(s, 4) + 4;
- if (nlen > MAXLCODES || ndist > MAXDCODES)
- return -3;
- short lengths[MAXCODES];
- int index;
- for (index = 0; index < ncode; index++)
- lengths[order[index]] = puff_bits(s, 3);
- for (; index < 19; index++)
- lengths[order[index]] = 0;
- short lencnt[MAXBITS + 1], lensym[MAXLCODES];
- struct puff_huffman lencode = {lencnt, lensym};
- int err = puff_construct(&lencode, lengths, 19);
- if (err != 0)
- return -4;
- index = 0;
- while (index < nlen + ndist) {
- int symbol;
- int len;
- symbol = puff_decode(s, &lencode);
- if (symbol < 0)
- return symbol;
- if (symbol < 16)
- lengths[index++] = symbol;
- else {
- len = 0;
- if (symbol == 16) {
- if (index == 0)
- return -5;
- len = lengths[index - 1];
- symbol = 3 + puff_bits(s, 2);
- } else if (symbol == 17)
- symbol = 3 + puff_bits(s, 3);
- else
- symbol = 11 + puff_bits(s, 7);
- if (index + symbol > nlen + ndist)
- return -6;
- while (symbol--)
- lengths[index++] = len;
- }
- }
- if (lengths[256] == 0)
- return -9;
- err = puff_construct(&lencode, lengths, nlen);
- if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
- return -7;
- short distcnt[MAXBITS + 1], distsym[MAXDCODES];
- struct puff_huffman distcode = {distcnt, distsym};
- err = puff_construct(&distcode, lengths + nlen, ndist);
- if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
- return -8;
- return puff_codes(s, &lencode, &distcode);
- }
- static int puff(unsigned char* dest, unsigned long* destlen,
- const unsigned char* source, unsigned long sourcelen)
- {
- struct puff_state s = {
- .out = dest,
- .outlen = *destlen,
- .outcnt = 0,
- .in = source,
- .inlen = sourcelen,
- .incnt = 0,
- .bitbuf = 0,
- .bitcnt = 0,
- };
- int err;
- if (setjmp(s.env) != 0)
- err = 2;
- else {
- int last;
- do {
- last = puff_bits(&s, 1);
- int type = puff_bits(&s, 2);
- err = type == 0 ? puff_stored(&s)
- : (type == 1 ? puff_fixed(&s)
- : (type == 2 ? puff_dynamic(&s) : -1));
- if (err != 0)
- break;
- } while (!last);
- }
- *destlen = s.outcnt;
- return err;
- }
- //% END CODE DERIVED FROM puff.{c,h}
- #define ZLIB_HEADER_WIDTH 2
- static int puff_zlib_to_file(const unsigned char* source,
- unsigned long sourcelen, int dest_fd)
- {
- if (sourcelen < ZLIB_HEADER_WIDTH)
- return 0;
- source += ZLIB_HEADER_WIDTH;
- sourcelen -= ZLIB_HEADER_WIDTH;
- const unsigned long max_destlen = 132 << 20;
- void* ret = mmap(0, max_destlen, PROT_WRITE | PROT_READ,
- MAP_PRIVATE | MAP_ANON, -1, 0);
- if (ret == MAP_FAILED)
- return -1;
- unsigned char* dest = (unsigned char*)ret;
- unsigned long destlen = max_destlen;
- int err = puff(dest, &destlen, source, sourcelen);
- if (err) {
- munmap(dest, max_destlen);
- errno = -err;
- return -1;
- }
- if (write(dest_fd, dest, destlen) != (ssize_t)destlen) {
- munmap(dest, max_destlen);
- return -1;
- }
- return munmap(dest, max_destlen);
- }
- static int setup_loop_device(unsigned char* data, unsigned long size,
- const char* loopname, int* loopfd_p)
- {
- int err = 0, loopfd = -1;
- int memfd = syscall(__NR_memfd_create, "syzkaller", 0);
- if (memfd == -1) {
- err = errno;
- goto error;
- }
- if (puff_zlib_to_file(data, size, memfd)) {
- err = errno;
- goto error_close_memfd;
- }
- loopfd = open(loopname, O_RDWR);
- if (loopfd == -1) {
- err = errno;
- goto error_close_memfd;
- }
- if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
- if (errno != EBUSY) {
- err = errno;
- goto error_close_loop;
- }
- ioctl(loopfd, LOOP_CLR_FD, 0);
- usleep(1000);
- if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
- err = errno;
- goto error_close_loop;
- }
- }
- close(memfd);
- *loopfd_p = loopfd;
- return 0;
- error_close_loop:
- close(loopfd);
- error_close_memfd:
- close(memfd);
- error:
- errno = err;
- return -1;
- }
- static void reset_loop_device(const char* loopname)
- {
- int loopfd = open(loopname, O_RDWR);
- if (loopfd == -1) {
- return;
- }
- if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
- }
- close(loopfd);
- }
- static long syz_mount_image(volatile long fsarg, volatile long dir,
- volatile long flags, volatile long optsarg,
- volatile long change_dir,
- volatile unsigned long size, volatile long image)
- {
- unsigned char* data = (unsigned char*)image;
- int res = -1, err = 0, need_loop_device = !!size;
- char* mount_opts = (char*)optsarg;
- char* target = (char*)dir;
- char* fs = (char*)fsarg;
- char* source = NULL;
- char loopname[64];
- if (need_loop_device) {
- int loopfd;
- memset(loopname, 0, sizeof(loopname));
- snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
- if (setup_loop_device(data, size, loopname, &loopfd) == -1)
- return -1;
- system("sync"); // 确保写入完成
- system("losetup -a"); // 调试用
- close(loopfd);
- source = loopname;
- }
- mkdir(target, 0777);
- char opts[256];
- memset(opts, 0, sizeof(opts));
- if (strlen(mount_opts) > (sizeof(opts) - 32)) {
- }
- strncpy(opts, mount_opts, sizeof(opts) - 32);
- if (strcmp(fs, "iso9660") == 0) {
- flags |= MS_RDONLY;
- } else if (strncmp(fs, "ext", 3) == 0) {
- bool has_remount_ro = false;
- char* remount_ro_start = strstr(opts, "errors=remount-ro");
- if (remount_ro_start != NULL) {
- char after = *(remount_ro_start + strlen("errors=remount-ro"));
- char before = remount_ro_start == opts ? '\0' : *(remount_ro_start - 1);
- has_remount_ro = ((before == '\0' || before == ',') &&
- (after == '\0' || after == ','));
- }
- if (strstr(opts, "errors=panic") || !has_remount_ro)
- strcat(opts, ",errors=continue");
- } else if (strcmp(fs, "xfs") == 0) {
- strcat(opts, ",nouuid");
- }
- res = mount(source, target, fs, flags, opts);
- if (res == -1) {
- err = errno;
- goto error_clear_loop;
- }
- res = open(target, O_RDONLY | O_DIRECTORY);
- if (res == -1) {
- err = errno;
- goto error_clear_loop;
- }
- if (change_dir) {
- res = chdir(target);
- if (res == -1) {
- err = errno;
- }
- }
- error_clear_loop:
- if (need_loop_device)
- reset_loop_device(loopname);
- errno = err;
- return res;
- }
- #define XT_TABLE_SIZE 1536
- #define XT_MAX_ENTRIES 10
- struct xt_counters {
- uint64_t pcnt, bcnt;
- };
- struct ipt_getinfo {
- char name[32];
- unsigned int valid_hooks;
- unsigned int hook_entry[5];
- unsigned int underflow[5];
- unsigned int num_entries;
- unsigned int size;
- };
- struct ipt_get_entries {
- char name[32];
- unsigned int size;
- uint64_t entrytable[XT_TABLE_SIZE / sizeof(uint64_t)];
- };
- struct ipt_replace {
- char name[32];
- unsigned int valid_hooks;
- unsigned int num_entries;
- unsigned int size;
- unsigned int hook_entry[5];
- unsigned int underflow[5];
- unsigned int num_counters;
- struct xt_counters* counters;
- uint64_t entrytable[XT_TABLE_SIZE / sizeof(uint64_t)];
- };
- struct ipt_table_desc {
- const char* name;
- struct ipt_getinfo info;
- struct ipt_replace replace;
- };
- static struct ipt_table_desc ipv4_tables[] = {
- {.name = "filter"}, {.name = "nat"}, {.name = "mangle"},
- {.name = "raw"}, {.name = "security"},
- };
- static struct ipt_table_desc ipv6_tables[] = {
- {.name = "filter"}, {.name = "nat"}, {.name = "mangle"},
- {.name = "raw"}, {.name = "security"},
- };
- #define IPT_BASE_CTL 64
- #define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
- #define IPT_SO_GET_INFO (IPT_BASE_CTL)
- #define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1)
- struct arpt_getinfo {
- char name[32];
- unsigned int valid_hooks;
- unsigned int hook_entry[3];
- unsigned int underflow[3];
- unsigned int num_entries;
- unsigned int size;
- };
- struct arpt_get_entries {
- char name[32];
- unsigned int size;
- uint64_t entrytable[XT_TABLE_SIZE / sizeof(uint64_t)];
- };
- struct arpt_replace {
- char name[32];
- unsigned int valid_hooks;
- unsigned int num_entries;
- unsigned int size;
- unsigned int hook_entry[3];
- unsigned int underflow[3];
- unsigned int num_counters;
- struct xt_counters* counters;
- uint64_t entrytable[XT_TABLE_SIZE / sizeof(uint64_t)];
- };
- struct arpt_table_desc {
- const char* name;
- struct arpt_getinfo info;
- struct arpt_replace replace;
- };
- static struct arpt_table_desc arpt_tables[] = {
- {.name = "filter"},
- };
- #define ARPT_BASE_CTL 96
- #define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
- #define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
- #define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
- static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables,
- int family, int level)
- {
- int fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (int i = 0; i < num_tables; i++) {
- struct ipt_table_desc* table = &tables[i];
- strcpy(table->info.name, table->name);
- strcpy(table->replace.name, table->name);
- socklen_t optlen = sizeof(table->info);
- if (getsockopt(fd, level, IPT_SO_GET_INFO, &table->info, &optlen)) {
- switch (errno) {
- case EPERM:
- case ENOENT:
- case ENOPROTOOPT:
- continue;
- }
- exit(1);
- }
- if (table->info.size > sizeof(table->replace.entrytable))
- exit(1);
- if (table->info.num_entries > XT_MAX_ENTRIES)
- exit(1);
- struct ipt_get_entries entries;
- memset(&entries, 0, sizeof(entries));
- strcpy(entries.name, table->name);
- entries.size = table->info.size;
- optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
- if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- exit(1);
- table->replace.valid_hooks = table->info.valid_hooks;
- table->replace.num_entries = table->info.num_entries;
- table->replace.size = table->info.size;
- memcpy(table->replace.hook_entry, table->info.hook_entry,
- sizeof(table->replace.hook_entry));
- memcpy(table->replace.underflow, table->info.underflow,
- sizeof(table->replace.underflow));
- memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
- }
- close(fd);
- }
- static void reset_iptables(struct ipt_table_desc* tables, int num_tables,
- int family, int level)
- {
- int fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (int i = 0; i < num_tables; i++) {
- struct ipt_table_desc* table = &tables[i];
- if (table->info.valid_hooks == 0)
- continue;
- struct ipt_getinfo info;
- memset(&info, 0, sizeof(info));
- strcpy(info.name, table->name);
- socklen_t optlen = sizeof(info);
- if (getsockopt(fd, level, IPT_SO_GET_INFO, &info, &optlen))
- exit(1);
- if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
- struct ipt_get_entries entries;
- memset(&entries, 0, sizeof(entries));
- strcpy(entries.name, table->name);
- entries.size = table->info.size;
- optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
- if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- exit(1);
- if (memcmp(table->replace.entrytable, entries.entrytable,
- table->info.size) == 0)
- continue;
- }
- struct xt_counters counters[XT_MAX_ENTRIES];
- table->replace.num_counters = info.num_entries;
- table->replace.counters = counters;
- optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
- table->replace.size;
- if (setsockopt(fd, level, IPT_SO_SET_REPLACE, &table->replace, optlen))
- exit(1);
- }
- close(fd);
- }
- static void checkpoint_arptables(void)
- {
- int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (unsigned i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
- struct arpt_table_desc* table = &arpt_tables[i];
- strcpy(table->info.name, table->name);
- strcpy(table->replace.name, table->name);
- socklen_t optlen = sizeof(table->info);
- if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &table->info, &optlen)) {
- switch (errno) {
- case EPERM:
- case ENOENT:
- case ENOPROTOOPT:
- continue;
- }
- exit(1);
- }
- if (table->info.size > sizeof(table->replace.entrytable))
- exit(1);
- if (table->info.num_entries > XT_MAX_ENTRIES)
- exit(1);
- struct arpt_get_entries entries;
- memset(&entries, 0, sizeof(entries));
- strcpy(entries.name, table->name);
- entries.size = table->info.size;
- optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
- if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- exit(1);
- table->replace.valid_hooks = table->info.valid_hooks;
- table->replace.num_entries = table->info.num_entries;
- table->replace.size = table->info.size;
- memcpy(table->replace.hook_entry, table->info.hook_entry,
- sizeof(table->replace.hook_entry));
- memcpy(table->replace.underflow, table->info.underflow,
- sizeof(table->replace.underflow));
- memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
- }
- close(fd);
- }
- static void reset_arptables()
- {
- int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (unsigned i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
- struct arpt_table_desc* table = &arpt_tables[i];
- if (table->info.valid_hooks == 0)
- continue;
- struct arpt_getinfo info;
- memset(&info, 0, sizeof(info));
- strcpy(info.name, table->name);
- socklen_t optlen = sizeof(info);
- if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &info, &optlen))
- exit(1);
- if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
- struct arpt_get_entries entries;
- memset(&entries, 0, sizeof(entries));
- strcpy(entries.name, table->name);
- entries.size = table->info.size;
- optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
- if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- exit(1);
- if (memcmp(table->replace.entrytable, entries.entrytable,
- table->info.size) == 0)
- continue;
- } else {
- }
- struct xt_counters counters[XT_MAX_ENTRIES];
- table->replace.num_counters = info.num_entries;
- table->replace.counters = counters;
- optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
- table->replace.size;
- if (setsockopt(fd, SOL_IP, ARPT_SO_SET_REPLACE, &table->replace, optlen))
- exit(1);
- }
- close(fd);
- }
- #define NF_BR_NUMHOOKS 6
- #define EBT_TABLE_MAXNAMELEN 32
- #define EBT_CHAIN_MAXNAMELEN 32
- #define EBT_BASE_CTL 128
- #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
- #define EBT_SO_GET_INFO (EBT_BASE_CTL)
- #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO + 1)
- #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES + 1)
- #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO + 1)
- struct ebt_replace {
- char name[EBT_TABLE_MAXNAMELEN];
- unsigned int valid_hooks;
- unsigned int nentries;
- unsigned int entries_size;
- struct ebt_entries* hook_entry[NF_BR_NUMHOOKS];
- unsigned int num_counters;
- struct ebt_counter* counters;
- char* entries;
- };
- struct ebt_entries {
- unsigned int distinguisher;
- char name[EBT_CHAIN_MAXNAMELEN];
- unsigned int counter_offset;
- int policy;
- unsigned int nentries;
- char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
- };
- struct ebt_table_desc {
- const char* name;
- struct ebt_replace replace;
- char entrytable[XT_TABLE_SIZE];
- };
- static struct ebt_table_desc ebt_tables[] = {
- {.name = "filter"},
- {.name = "nat"},
- {.name = "broute"},
- };
- static void checkpoint_ebtables(void)
- {
- int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (size_t i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
- struct ebt_table_desc* table = &ebt_tables[i];
- strcpy(table->replace.name, table->name);
- socklen_t optlen = sizeof(table->replace);
- if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_INFO, &table->replace,
- &optlen)) {
- switch (errno) {
- case EPERM:
- case ENOENT:
- case ENOPROTOOPT:
- continue;
- }
- exit(1);
- }
- if (table->replace.entries_size > sizeof(table->entrytable))
- exit(1);
- table->replace.num_counters = 0;
- table->replace.entries = table->entrytable;
- optlen = sizeof(table->replace) + table->replace.entries_size;
- if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace,
- &optlen))
- exit(1);
- }
- close(fd);
- }
- static void reset_ebtables()
- {
- int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- switch (errno) {
- case EAFNOSUPPORT:
- case ENOPROTOOPT:
- case ENOENT:
- return;
- }
- exit(1);
- }
- for (unsigned i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
- struct ebt_table_desc* table = &ebt_tables[i];
- if (table->replace.valid_hooks == 0)
- continue;
- struct ebt_replace replace;
- memset(&replace, 0, sizeof(replace));
- strcpy(replace.name, table->name);
- socklen_t optlen = sizeof(replace);
- if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
- exit(1);
- replace.num_counters = 0;
- table->replace.entries = 0;
- for (unsigned h = 0; h < NF_BR_NUMHOOKS; h++)
- table->replace.hook_entry[h] = 0;
- if (memcmp(&table->replace, &replace, sizeof(table->replace)) == 0) {
- char entrytable[XT_TABLE_SIZE];
- memset(&entrytable, 0, sizeof(entrytable));
- replace.entries = entrytable;
- optlen = sizeof(replace) + replace.entries_size;
- if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
- exit(1);
- if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
- continue;
- }
- for (unsigned j = 0, h = 0; h < NF_BR_NUMHOOKS; h++) {
- if (table->replace.valid_hooks & (1 << h)) {
- table->replace.hook_entry[h] =
- (struct ebt_entries*)table->entrytable + j;
- j++;
- }
- }
- table->replace.entries = table->entrytable;
- optlen = sizeof(table->replace) + table->replace.entries_size;
- if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
- exit(1);
- }
- close(fd);
- }
- static void checkpoint_net_namespace(void)
- {
- checkpoint_ebtables();
- checkpoint_arptables();
- checkpoint_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
- AF_INET, SOL_IP);
- checkpoint_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
- AF_INET6, SOL_IPV6);
- }
- static void reset_net_namespace(void)
- {
- reset_ebtables();
- reset_arptables();
- reset_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
- AF_INET, SOL_IP);
- reset_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
- AF_INET6, SOL_IPV6);
- }
- static void setup_gadgetfs();
- static void setup_binderfs();
- static void setup_fusectl();
- static void sandbox_common_mount_tmpfs(void)
- {
- write_file("/proc/sys/fs/mount-max", "100000");
- if (mkdir("./syz-tmp", 0777))
- exit(1);
- if (mount("", "./syz-tmp", "tmpfs", 0, NULL))
- exit(1);
- if (mkdir("./syz-tmp/newroot", 0777))
- exit(1);
- if (mkdir("./syz-tmp/newroot/dev", 0700))
- exit(1);
- unsigned bind_mount_flags = MS_BIND | MS_REC | MS_PRIVATE;
- if (mount("/dev", "./syz-tmp/newroot/dev", NULL, bind_mount_flags, NULL))
- exit(1);
- if (mkdir("./syz-tmp/newroot/proc", 0700))
- exit(1);
- if (mount("syz-proc", "./syz-tmp/newroot/proc", "proc", 0, NULL))
- exit(1);
- if (mkdir("./syz-tmp/newroot/selinux", 0700))
- exit(1);
- const char* selinux_path = "./syz-tmp/newroot/selinux";
- if (mount("/selinux", selinux_path, NULL, bind_mount_flags, NULL)) {
- if (errno != ENOENT)
- exit(1);
- if (mount("/sys/fs/selinux", selinux_path, NULL, bind_mount_flags, NULL) &&
- errno != ENOENT)
- exit(1);
- }
- if (mkdir("./syz-tmp/newroot/sys", 0700))
- exit(1);
- if (mount("/sys", "./syz-tmp/newroot/sys", 0, bind_mount_flags, NULL))
- exit(1);
- if (mount("/sys/kernel/debug", "./syz-tmp/newroot/sys/kernel/debug", NULL,
- bind_mount_flags, NULL) &&
- errno != ENOENT)
- exit(1);
- if (mount("/sys/fs/smackfs", "./syz-tmp/newroot/sys/fs/smackfs", NULL,
- bind_mount_flags, NULL) &&
- errno != ENOENT)
- exit(1);
- if (mount("/proc/sys/fs/binfmt_misc",
- "./syz-tmp/newroot/proc/sys/fs/binfmt_misc", NULL, bind_mount_flags,
- NULL) &&
- errno != ENOENT)
- exit(1);
- if (mkdir("./syz-tmp/newroot/syz-inputs", 0700))
- exit(1);
- if (mount("/syz-inputs", "./syz-tmp/newroot/syz-inputs", NULL,
- bind_mount_flags | MS_RDONLY, NULL) &&
- errno != ENOENT)
- exit(1);
- if (mkdir("./syz-tmp/pivot", 0777))
- exit(1);
- if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) {
- if (chdir("./syz-tmp"))
- exit(1);
- } else {
- if (chdir("/"))
- exit(1);
- if (umount2("./pivot", MNT_DETACH))
- exit(1);
- }
- if (chroot("./newroot"))
- exit(1);
- if (chdir("/"))
- exit(1);
- setup_gadgetfs();
- setup_binderfs();
- setup_fusectl();
- }
- static void setup_gadgetfs()
- {
- if (mkdir("/dev/gadgetfs", 0777)) {
- }
- if (mount("gadgetfs", "/dev/gadgetfs", "gadgetfs", 0, NULL)) {
- }
- }
- static void setup_fusectl()
- {
- if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
- }
- }
- static void setup_binderfs()
- {
- if (mkdir("/dev/binderfs", 0777)) {
- }
- if (mount("binder", "/dev/binderfs", "binder", 0, NULL)) {
- }
- }
- static void loop();
- static void sandbox_common()
- {
- prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- if (getppid() == 1)
- exit(1);
- struct rlimit rlim;
- rlim.rlim_cur = rlim.rlim_max = (200 << 20);
- setrlimit(RLIMIT_AS, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 32 << 20;
- setrlimit(RLIMIT_MEMLOCK, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 136 << 20;
- setrlimit(RLIMIT_FSIZE, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 1 << 20;
- setrlimit(RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 128 << 20;
- setrlimit(RLIMIT_CORE, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 256;
- setrlimit(RLIMIT_NOFILE, &rlim);
- if (unshare(CLONE_NEWNS)) {
- }
- if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)) {
- }
- if (unshare(CLONE_NEWIPC)) {
- }
- if (unshare(0x02000000)) {
- }
- if (unshare(CLONE_NEWUTS)) {
- }
- if (unshare(CLONE_SYSVSEM)) {
- }
- typedef struct {
- const char* name;
- const char* value;
- } sysctl_t;
- static const sysctl_t sysctls[] = {
- {"/proc/sys/kernel/shmmax", "16777216"},
- {"/proc/sys/kernel/shmall", "536870912"},
- {"/proc/sys/kernel/shmmni", "1024"},
- {"/proc/sys/kernel/msgmax", "8192"},
- {"/proc/sys/kernel/msgmni", "1024"},
- {"/proc/sys/kernel/msgmnb", "1024"},
- {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
- };
- unsigned i;
- for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
- write_file(sysctls[i].name, sysctls[i].value);
- }
- static int wait_for_loop(int pid)
- {
- if (pid < 0)
- exit(1);
- int status = 0;
- while (waitpid(-1, &status, __WALL) != pid) {
- }
- return WEXITSTATUS(status);
- }
- static void drop_caps(void)
- {
- struct __user_cap_header_struct cap_hdr = {};
- struct __user_cap_data_struct cap_data[2] = {};
- cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
- cap_hdr.pid = getpid();
- if (syscall(SYS_capget, &cap_hdr, &cap_data))
- exit(1);
- const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
- cap_data[0].effective &= ~drop;
- cap_data[0].permitted &= ~drop;
- cap_data[0].inheritable &= ~drop;
- if (syscall(SYS_capset, &cap_hdr, &cap_data))
- exit(1);
- }
- static int do_sandbox_none(void)
- {
- if (unshare(CLONE_NEWPID)) {
- }
- int pid = fork();
- if (pid != 0)
- return wait_for_loop(pid);
- sandbox_common();
- drop_caps();
- initialize_netdevices_init();
- if (unshare(CLONE_NEWNET)) {
- }
- write_file("/proc/sys/net/ipv4/ping_group_range", "0 65535");
- initialize_netdevices();
- sandbox_common_mount_tmpfs();
- loop();
- exit(1);
- }
- #define FS_IOC_SETFLAGS _IOW('f', 2, long)
- static void remove_dir(const char* dir)
- {
- int iter = 0;
- DIR* dp = 0;
- const int umount_flags = MNT_FORCE | UMOUNT_NOFOLLOW;
- retry:
- while (umount2(dir, umount_flags) == 0) {
- }
- dp = opendir(dir);
- if (dp == NULL) {
- if (errno == EMFILE) {
- exit(1);
- }
- exit(1);
- }
- struct dirent* ep = 0;
- while ((ep = readdir(dp))) {
- if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
- continue;
- char filename[FILENAME_MAX];
- snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
- while (umount2(filename, umount_flags) == 0) {
- }
- struct stat st;
- if (lstat(filename, &st))
- exit(1);
- if (S_ISDIR(st.st_mode)) {
- remove_dir(filename);
- continue;
- }
- int i;
- for (i = 0;; i++) {
- if (unlink(filename) == 0)
- break;
- if (errno == EPERM) {
- int fd = open(filename, O_RDONLY);
- if (fd != -1) {
- long flags = 0;
- if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
- }
- close(fd);
- continue;
- }
- }
- if (errno == EROFS) {
- break;
- }
- if (errno != EBUSY || i > 100)
- exit(1);
- if (umount2(filename, umount_flags))
- exit(1);
- }
- }
- closedir(dp);
- for (int i = 0;; i++) {
- if (rmdir(dir) == 0)
- break;
- if (i < 100) {
- if (errno == EPERM) {
- int fd = open(dir, O_RDONLY);
- if (fd != -1) {
- long flags = 0;
- if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
- }
- close(fd);
- continue;
- }
- }
- if (errno == EROFS) {
- break;
- }
- if (errno == EBUSY) {
- if (umount2(dir, umount_flags))
- exit(1);
- continue;
- }
- if (errno == ENOTEMPTY) {
- if (iter < 100) {
- iter++;
- goto retry;
- }
- }
- }
- exit(1);
- }
- }
- static void kill_and_wait(int pid, int* status)
- {
- kill(-pid, SIGKILL);
- kill(pid, SIGKILL);
- for (int i = 0; i < 100; i++) {
- if (waitpid(-1, status, WNOHANG | __WALL) == pid)
- return;
- usleep(1000);
- }
- DIR* dir = opendir("/sys/fs/fuse/connections");
- if (dir) {
- for (;;) {
- struct dirent* ent = readdir(dir);
- if (!ent)
- break;
- if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
- continue;
- char abort[300];
- snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
- ent->d_name);
- int fd = open(abort, O_WRONLY);
- if (fd == -1) {
- continue;
- }
- if (write(fd, abort, 1) < 0) {
- }
- close(fd);
- }
- closedir(dir);
- } else {
- }
- while (waitpid(-1, status, __WALL) != pid) {
- }
- }
- static void setup_loop()
- {
- checkpoint_net_namespace();
- }
- static void reset_loop()
- {
- char buf[64];
- snprintf(buf, sizeof(buf), "/dev/loop%llu", procid);
- int loopfd = open(buf, O_RDWR);
- if (loopfd != -1) {
- ioctl(loopfd, LOOP_CLR_FD, 0);
- close(loopfd);
- }
- reset_net_namespace();
- }
- static void setup_test()
- {
- prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- setpgrp();
- write_file("/proc/self/oom_score_adj", "1000");
- if (symlink("/dev/binderfs", "./binderfs")) {
- }
- }
- static void close_fds()
- {
- for (int fd = 3; fd < MAX_FDS; fd++)
- close(fd);
- }
- static void setup_sysctl()
- {
- int cad_pid = fork();
- if (cad_pid < 0)
- exit(1);
- if (cad_pid == 0) {
- for (;;)
- sleep(100);
- }
- char tmppid[32];
- snprintf(tmppid, sizeof(tmppid), "%d", cad_pid);
- struct {
- const char* name;
- const char* data;
- } files[] = {
- {"/sys/kernel/debug/x86/nmi_longest_ns", "10000000000"},
- {"/proc/sys/kernel/hung_task_check_interval_secs", "20"},
- {"/proc/sys/net/core/bpf_jit_kallsyms", "1"},
- {"/proc/sys/net/core/bpf_jit_harden", "0"},
- {"/proc/sys/kernel/kptr_restrict", "0"},
- {"/proc/sys/kernel/softlockup_all_cpu_backtrace", "1"},
- {"/proc/sys/fs/mount-max", "100"},
- {"/proc/sys/vm/oom_dump_tasks", "0"},
- {"/proc/sys/debug/exception-trace", "0"},
- {"/proc/sys/kernel/printk", "7 4 1 3"},
- {"/proc/sys/kernel/keys/gc_delay", "1"},
- {"/proc/sys/vm/oom_kill_allocating_task", "1"},
- {"/proc/sys/kernel/ctrl-alt-del", "0"},
- {"/proc/sys/kernel/cad_pid", tmppid},
- };
- for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
- if (!write_file(files[i].name, files[i].data)) {
- }
- }
- kill(cad_pid, SIGKILL);
- while (waitpid(cad_pid, NULL, 0) != cad_pid)
- ;
- }
- struct thread_t {
- int created, call;
- event_t ready, done;
- };
- static struct thread_t threads[16];
- static void execute_call(int call);
- static int running;
- static void* thr(void* arg)
- {
- struct thread_t* th = (struct thread_t*)arg;
- for (;;) {
- event_wait(&th->ready);
- event_reset(&th->ready);
- execute_call(th->call);
- __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
- event_set(&th->done);
- }
- return 0;
- }
- static void execute_one(void)
- {
- if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
- }
- int i, call, thread;
- for (call = 0; call < 13; call++) {
- for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
- thread++) {
- struct thread_t* th = &threads[thread];
- if (!th->created) {
- th->created = 1;
- event_init(&th->ready);
- event_init(&th->done);
- event_set(&th->done);
- thread_start(thr, th);
- }
- if (!event_isset(&th->done))
- continue;
- event_reset(&th->done);
- th->call = call;
- __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
- event_set(&th->ready);
- if (call == 0 || call == 2 || call == 10)
- break;
- event_timedwait(&th->done,
- 50 + (call == 0 ? 4000 : 0) + (call == 1 ? 4000 : 0));
- break;
- }
- }
- for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
- sleep_ms(1);
- close_fds();
- }
- static void execute_one(void);
- #define WAIT_FLAGS __WALL
- static void loop(void)
- {
- setup_loop();
- int iter = 0;
- for (;; iter++) {
- char cwdbuf[32];
- sprintf(cwdbuf, "./%d", iter);
- if (mkdir(cwdbuf, 0777))
- exit(1);
- reset_loop();
- int pid = fork();
- if (pid < 0)
- exit(1);
- if (pid == 0) {
- if (chdir(cwdbuf))
- exit(1);
- setup_test();
- execute_one();
- exit(0);
- }
- int status = 0;
- uint64_t start = current_time_ms();
- for (;;) {
- sleep_ms(10);
- if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
- break;
- if (current_time_ms() - start < 5000)
- continue;
- kill_and_wait(pid, &status);
- break;
- }
- remove_dir(cwdbuf);
- }
- }
- uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
- void execute_call(int call)
- {
- intptr_t res = 0;
- switch (call) {
- case 0:
- NONFAILING(memcpy((void*)0x200000000000, "ext4\000", 5));
- NONFAILING(memcpy((void*)0x200000000280, "./bus\000", 6));
- NONFAILING(memcpy((void*)0x200000000440, "dax=always", 10));
- NONFAILING(*(uint8_t*)0x20000000044a = 0x2c);
- NONFAILING(memcpy((void*)0x20000000044b, "journal_ioprio", 14));
- NONFAILING(*(uint8_t*)0x200000000459 = 0x3d);
- NONFAILING(sprintf((char*)0x20000000045a, "0x%016llx", (long long)2));
- NONFAILING(*(uint8_t*)0x20000000046c = 0x2c);
- NONFAILING(memcpy((void*)0x20000000046d, "mb_optimize_scan", 16));
- NONFAILING(*(uint8_t*)0x20000000047d = 0x3d);
- NONFAILING(sprintf((char*)0x20000000047e, "0x%016llx", (long long)1));
- NONFAILING(*(uint8_t*)0x200000000490 = 0x2c);
- NONFAILING(memcpy((void*)0x200000000491, "lazytime", 8));
- NONFAILING(*(uint8_t*)0x200000000499 = 0x2c);
- NONFAILING(memcpy((void*)0x20000000049a, "i_version", 9));
- NONFAILING(*(uint8_t*)0x2000000004a3 = 0x2c);
- NONFAILING(memcpy((void*)0x2000000004a4, "data_err=ignore", 15));
- NONFAILING(*(uint8_t*)0x2000000004b3 = 0x2c);
- NONFAILING(*(uint8_t*)0x2000000004b4 = 0);
- NONFAILING(memcpy(
- (void*)0x200000000500,
- "\x78\x9c\xec\xdb\xcf\x4f\x1c\x55\x1c\x00\xf0\xef\xcc\x02\x95\xfe\x10"
- "\xac\xf5\x47\x69\x55\xb4\x1a\x89\x3f\xa0\xd0\xaa\x3d\x78\xd1\x68\xe2"
- "\x41\x13\x13\x3d\xd4\x23\x02\x6d\xb0\xdb\x62\x0a\x26\xb6\x21\x8a\xc6"
- "\xd4\xa3\x69\xe2\xdd\x78\x34\xf1\x2f\xf0\xa4\x17\xa3\x9e\x4c\xbc\xea"
- "\xdd\x34\x69\x0c\x97\x56\x4f\x6b\x66\x77\x06\x96\x65\x97\x02\x5d\x58"
- "\xed\x7e\x3e\xc9\xb4\xef\xcd\xbc\xcd\x7b\xdf\x7d\xf3\x76\xdf\x9b\xc7"
- "\x06\xd0\xb5\x86\xb3\x7f\x92\x88\xfd\x11\xf1\x7b\x44\x0c\xd4\xb2\x6b"
- "\x0b\x0c\xd7\xfe\xbb\xb9\xbc\x38\xf5\xf7\xf2\xe2\x54\x12\x95\xca\x5b"
- "\x7f\x25\xd5\x72\x37\x96\x17\xa7\x8a\xa2\xc5\xeb\xf6\xe5\x99\x91\x34"
- "\x22\xfd\x2c\x89\x23\x4d\xea\x9d\xbf\x74\xf9\xdc\x64\xb9\x3c\x73\x31"
- "\xcf\x8f\x2d\x9c\x7f\x7f\x6c\xfe\xd2\xe5\x67\x67\xcf\x4f\x9e\x9d\x39"
- "\x3b\x73\x61\xe2\xd4\xa9\x93\x27\xc6\x5f\x78\x7e\xe2\xb9\xb6\xc4\x99"
- "\xc5\x75\x63\xe8\xa3\xb9\xa3\x87\x5f\x7b\xe7\xea\x1b\x53\xa7\xaf\xbe"
- "\xfb\xf3\xb7\x49\x11\x7f\x43\x1c\x6d\x32\xbc\xd1\xc5\x27\x2a\x95\x36"
- "\x57\xd7\x59\x07\xea\xd2\x49\x4f\x07\x1b\xc2\x96\x94\x22\x22\xeb\xae"
- "\xde\xea\xf8\x1f\x88\x52\xac\x76\xde\x40\xbc\xfa\x69\x47\x1b\x07\xec"
- "\xa8\x4a\xae\xc5\xe5\xa5\x0a\x70\x07\x4b\xa2\xd3\x2d\x00\x3a\xa3\xf8"
- "\xa2\xcf\xd6\xbf\xc5\xb1\x7b\xb3\x8f\xce\xbb\xfe\x52\x6d\x01\x94\xc5"
- "\x7d\x33\x3f\x6a\x57\x7a\x22\xcd\xcb\xf4\x36\xac\x6f\xdb\x69\x38\x22"
- "\x4e\x2f\xfd\xf3\x55\x76\xc4\xce\x3c\x87\x00\x00\x58\xe3\xfb\x6c\xfe"
- "\xf3\x4c\xb3\xf9\x5f\x1a\xf7\xd7\x95\xbb\x3b\xdf\x43\x19\x8c\x88\x7b"
- "\x22\xe2\x60\x44\xdc\x1b\x11\x87\x22\xe2\xbe\x88\x6a\xd9\x07\x22\xe2"
- "\xc1\x2d\xd6\xdf\xb8\x49\xb2\x7e\xfe\x93\x5e\xdb\x56\x60\x9b\x94\xcd"
- "\xff\x5e\xcc\xf7\xb6\xd6\xce\xff\x8a\xd9\x5f\x0c\x96\xf2\xdc\x81\x6a"
- "\xfc\xbd\xc9\x99\xd9\xf2\xcc\xf1\xfc\x3d\x19\x89\xde\x3d\x59\x7e\x7c"
- "\x83\x3a\x7e\x78\xe5\xb7\x2f\x5a\x5d\xab\x9f\xff\x65\x47\x56\x7f\x31"
- "\x17\xcc\xdb\x71\xad\x67\xcf\xda\xd7\x4c\x4f\x2e\x4c\xde\x4e\xcc\xf5"
- "\xae\x7f\x12\x31\xd4\xd3\x2c\xfe\x64\x65\x27\x20\x89\x88\xc3\x11\x31"
- "\xb4\xcd\x3a\x66\x9f\xfa\xe6\x68\xab\x6b\xb7\x8e\x7f\x03\x6d\xd8\x67"
- "\xaa\x7c\x1d\xf1\x64\xad\xff\x97\xa2\x21\xfe\x42\xb2\xf1\xfe\xe4\xd8"
- "\x5d\x51\x9e\x39\x3e\x56\xdc\x15\xeb\xfd\xf2\xeb\x95\x37\x5b\xd5\x7f"
- "\x5b\xf1\xb7\x41\xd6\xff\x7b\x9b\xde\xff\x2b\xf1\x0f\x26\xf5\xfb\xb5"
- "\xf3\x5b\xaf\xe3\xca\x1f\x9f\xb7\x5c\xd3\x6c\xf7\xfe\xef\x4b\xde\xae"
- "\xa6\xfb\xf2\x73\x1f\x4e\x2e\x2c\x5c\x1c\x8f\xe8\x4b\x5e\xaf\x35\xba"
- "\xfe\xfc\xc4\xea\x6b\x8b\x7c\x51\x3e\x8b\x7f\xe4\x58\xf3\xf1\x7f\x30"
- "\x56\xdf\x89\x23\x11\x91\xdd\xc4\x0f\x45\xc4\xc3\x11\xf1\x48\xde\xf6"
- "\x47\x23\xe2\xb1\x88\x38\xb6\x41\xfc\x3f\xbd\xfc\xf8\x7b\xdb\x8f\x7f"
- "\x67\x65\xf1\x4f\x6f\xa9\xff\x57\x13\x7d\xd1\x78\xa6\x79\xa2\x74\xee"
- "\xc7\xef\xd6\x54\x3a\xb8\x95\xf8\xb3\xfe\x3f\x59\x4d\x8d\xe4\x67\x36"
- "\xf3\xf9\xb7\x99\x76\x6d\xef\x6e\x06\x00\x00\x80\xff\x9f\x34\x22\xf6"
- "\x47\x92\x8e\xae\xa4\xd3\x74\x74\xb4\xf6\x37\xfc\x87\x62\x6f\x5a\x9e"
- "\x9b\x5f\x78\xfa\xcc\xdc\x07\x17\xa6\x6b\xbf\x11\x18\x8c\xde\xb4\x78"
- "\xd2\x35\x50\xf7\x3c\x74\x3c\x5f\xd6\x17\xf9\x89\x86\xfc\x89\xfc\xb9"
- "\xf1\x97\xa5\xfe\x6a\x7e\x74\x6a\xae\x3c\xdd\xe9\xe0\xa1\xcb\xed\x6b"
- "\x31\xfe\x33\x7f\x96\x3a\xdd\x3a\x60\xc7\xf9\xbd\x16\x74\x2f\xe3\x1f"
- "\xba\x97\xf1\x0f\xdd\xcb\xf8\x87\xee\xd5\x64\xfc\xf7\x77\xa2\x1d\xc0"
- "\xee\x6b\xf6\xfd\xff\x71\x07\xda\x01\xec\xbe\x86\xf1\x6f\xdb\x0f\xba"
- "\x88\xf5\x3f\x74\x2f\xe3\x1f\xba\x97\xf1\x0f\x5d\x69\xbe\x3f\x6e\xfd"
- "\x23\x79\x09\x89\x75\x89\x48\xff\x13\xcd\x90\xd8\xa1\x44\xa7\x3f\x99"
- "\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\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\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\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\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\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\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\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\xda\xe3\xdf\x00\x00\x00\xff\xff\x08\x33"
- "\xea\xc4",
- 1073));
- char cmd[256];
- sprintf(cmd, "fsck -y /dev/loop%llu", procid);
- system(cmd);
- NONFAILING(syz_mount_image(
- /*fs=*/0x200000000000, /*dir=*/0x200000000280,
- /*flags=MS_PRIVATE|MS_POSIXACL|MS_REC|MS_RELATIME|MS_NODEV|0x80*/
- 0x254084, /*opts=*/0x200000000440, /*chdir=*/1, /*size=*/0x431,
- /*img=*/0x200000000500));
- break;
- case 1:
- NONFAILING(memcpy((void*)0x200000000040, "ext4\000", 5));
- NONFAILING(memcpy((void*)0x2000000000c0, "./file0\000", 8));
- NONFAILING(*(uint8_t*)0x200000000300 = 0);
- NONFAILING(memcpy(
- (void*)0x200000000800,
- "\x78\x9c\xec\xdd\xcd\x6b\x1c\xe5\x1f\x00\xf0\xef\x6c\x92\x26\xbf\xb4"
- "\x3f\x13\x41\xd0\x7a\x0a\x08\x1a\xa8\xdd\x98\x1a\x5b\x05\x0f\x15\x0f"
- "\x22\x58\x28\xe8\xd9\x74\xd9\x6c\x43\xcd\x26\x5b\xb2\x9b\xd2\x84\x40"
- "\x2d\x22\x78\x11\x54\x3c\x08\x7a\xe9\xd9\x97\x7a\xf3\xea\xcb\x55\xff"
- "\x0b\x0f\xd2\x52\x35\x2d\x56\x3c\x48\x64\x36\xb3\xed\xb6\xd9\x4d\x13"
- "\x9b\x6c\x52\xf7\xf3\x81\xa7\x7d\x9e\x99\x67\xf3\xcc\x77\x9f\x99\x79"
- "\x9e\xdd\x19\x76\x02\xe8\x5a\x23\xe9\x3f\xb9\x88\x83\x11\xf1\x41\x12"
- "\x31\x94\x2d\x4f\x22\xa2\xaf\x9e\xeb\x8d\x38\xbe\x56\xef\xe6\xca\x72"
- "\x31\x4d\x49\xac\xae\xbe\xfe\x5b\x52\xaf\x73\x63\x65\xb9\x18\x4d\xaf"
- "\x49\xed\xcf\x0a\x8f\x45\xc4\xf7\xef\x46\x1c\xca\x25\xeb\xda\xad\x2e"
- "\x2e\xcd\x14\xca\xe5\xd2\x7c\x56\x1e\xab\xcd\x9e\x1d\xab\x2e\x2e\x1d"
- "\x3e\x33\x5b\x98\x2e\x4d\x97\xe6\x8e\x8e\x4f\x4c\x1c\x39\xf6\xdc\xb1"
- "\xa3\xdb\x17\xeb\x1f\x3f\x2d\x1d\xb8\xfa\xe1\x2b\x4f\x7d\x75\xfc\xaf"
- "\x77\x1e\xbd\xfc\xfe\x0f\x49\x1c\x8f\x03\xd9\xba\xe6\x38\xb6\xcb\x48"
- "\x8c\x64\xef\x49\x5f\xfa\x16\xde\xe1\xe5\xed\x6e\x6c\x97\xad\xef\x61"
- "\x1e\x04\xb9\x88\xe8\x59\x3b\xca\xe3\x60\x0c\x45\x4f\x3d\x07\x00\xfc"
- "\x97\x5d\x88\x88\x55\x00\xa0\xcb\x24\xc6\x7f\x00\xe8\x32\x8d\xef\x01"
- "\x6e\xac\x2c\x17\x1b\x69\x77\xbf\x91\xe8\xac\x6b\x2f\x45\xc4\xc0\x5a"
- "\xfc\x8d\xeb\x9b\x6b\x6b\x7a\xb3\x6b\x76\x03\xf5\xeb\xa0\x83\x37\x92"
- "\x3b\xae\x8c\x24\x11\x31\xbc\x0d\xed\x8f\x44\xc4\x67\xdf\xbc\xf9\x45"
- "\x9a\x62\x87\xae\x43\x02\xb4\xf2\xf6\xc5\x88\x38\x35\x3c\xb2\xfe\xfc"
- "\x9f\xac\xbb\x67\x61\xab\x9e\xd9\x44\x9d\x91\xbb\xca\xce\x7f\xd0\x39"
- "\xdf\xa6\xf3\x9f\xe7\x5b\xcd\xff\x72\xb7\xe6\x3f\xd1\x62\xfe\xd3\xdf"
- "\xe2\xd8\xfd\x37\xee\x7d\xfc\xe7\xae\x6c\x43\x33\x6d\xa5\xf3\xbf\x17"
- "\x9b\xee\x6d\xbb\xd9\x14\x7f\x66\xb8\x27\x2b\xfd\xbf\x3e\xe7\xeb\x4b"
- "\x4e\x9f\x29\x97\xd2\x73\xdb\x43\x11\x31\x1a\x7d\xfd\x69\x79\x7c\x83"
- "\x36\x46\xaf\xff\x7d\xbd\xdd\xba\xe6\xf9\xdf\xef\x1f\xbd\xf5\x79\xda"
- "\x7e\xfa\xff\xed\x1a\xb9\x2b\xbd\xfd\x77\xbe\x66\xaa\x50\x2b\xdc\x4f"
- "\xcc\xcd\xae\x5d\x8c\x78\xbc\xb7\x55\xfc\xc9\xad\xfe\x4f\xda\xcc\x7f"
- "\x4f\x6e\xb2\x8d\x57\x5f\x78\xef\xd3\x76\xeb\xd2\xf8\xd3\x78\x1b\x69"
- "\x7d\xfc\x3b\x6b\xf5\x52\xc4\x93\x2d\xfb\xff\xf6\x1d\x6d\xc9\x86\xf7"
- "\x27\x8e\xd5\x77\x87\xb1\xc6\x4e\xd1\xc2\xd7\x3f\x7f\x32\xd8\xae\xfd"
- "\xe6\xfe\x4f\x53\xda\x7e\xe3\xb3\x40\x27\xa4\xfd\x3f\xb8\x71\xfc\xc3"
- "\x49\xf3\xfd\x9a\xd5\xad\xb7\xf1\xe3\xa5\xa1\xef\xda\xad\x6b\x19\xff"
- "\x85\xe6\x1a\xad\xf7\xff\x7d\xc9\x1b\xf5\xfc\xbe\x6c\xd9\xf9\x42\xad"
- "\x36\x3f\x1e\xb1\x2f\x79\x6d\xfd\xf2\x23\xb7\x5f\xdb\x28\x37\xea\xa7"
- "\xf1\x8f\x3e\xd1\xfa\xf8\xdf\x68\xff\x4f\x3f\x13\x9e\xda\x64\xfc\xbd"
- "\x57\x7f\xfd\x72\x4b\xf1\x77\xb8\xff\xa7\xb6\xd4\xff\x5b\xcf\x5c\xbe"
- "\x39\xd3\xd3\xae\xfd\x7b\xc7\x9f\xf6\xff\x44\x3d\x37\x9a\x2d\xd9\xcc"
- "\xf9\x6f\xb3\x1b\x78\x3f\xef\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x56\x2e\x22\x0e\x44\x92"
- "\xcb\xdf\xca\xe7\x72\xf9\xfc\xda\x33\xbc\x1f\x89\xc1\x5c\xb9\x52\xad"
- "\x1d\x3a\x5d\x59\x98\x9b\x8a\xfa\xb3\xb2\x87\xa3\x2f\xd7\xf8\xa9\xcb"
- "\xa1\xa6\xdf\x43\x1d\xcf\x7e\x0f\xbf\x51\x3e\x72\x57\xf9\xd9\x88\x78"
- "\x38\x22\x3e\xee\xff\x5f\xbd\x9c\x2f\x56\xca\x53\xbb\x1d\x3c\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\x00\x00\x00\x00\x00\x64\xf6\xb7\x79\xfe"
- "\x7f\xea\x97\xfe\xdd\xde\x3a\x00\x60\xc7\x0c\xec\xf6\x06\x00\x00\x1d"
- "\x67\xfc\x07\x80\xee\x63\xfc\x07\x80\xee\x63\xfc\x07\x80\xee\x63\xfc"
- "\x07\x80\xee\x63\xfc\x07\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\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x60\x87\x9d\x3c\x71\x22\x4d\xab\x7f\xae\x2c\x17"
- "\xd3\xf2\xd4\xb9\xc5\x85\x99\xca\xb9\xc3\x53\xa5\xea\x4c\x7e\x76\xa1"
- "\x98\x2f\x56\xe6\xcf\xe6\xa7\x2b\x95\xe9\x72\x29\x5f\xac\xcc\xde\xeb"
- "\xef\x95\x2b\x95\xb3\x13\x31\xb7\x70\x7e\xac\x56\xaa\xd6\xc6\xaa\x8b"
- "\x4b\x93\xb3\x95\x85\xb9\xda\xe4\x99\xd9\xc2\x74\x69\xb2\xd4\xd7\x91"
- "\xa8\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\x00\x00\x00\x00\x00\x60\x6b"
- "\xaa\x8b\x4b\x33\x85\x72\xb9\x34\xdf\x9d\x99\x81\xd8\x13\x9b\x21\xd3"
- "\xc1\xcc\xe4\xe8\xd3\xc9\x1e\xd8\x8c\xbd\x9e\xd9\xed\x33\x13\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\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\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\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"
- "\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\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\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\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\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\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\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\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\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\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\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\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\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\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\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\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\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"
- "\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\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\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\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\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\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\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\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\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\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\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\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\xc0\x83\xe1\x9f\x00\x00\x00\xff\xff\x4a\x6a\x27\x06",
- 1903));
- sprintf(cmd, "fsck -y /dev/loop%llu", procid);
- system(cmd);
- NONFAILING(syz_mount_image(
- /*fs=*/0x200000000040, /*dir=*/0x2000000000c0,
- /*flags=MS_SYNCHRONOUS|MS_NOSUID|MS_NODIRATIME|MS_NOATIME*/ 0xc12,
- /*opts=*/0x200000000300, /*chdir=*/1, /*size=*/0x76f,
- /*img=*/0x200000000800));
- break;
- case 2:
- NONFAILING(*(uint64_t*)0x200000000100 = -1);
- NONFAILING(*(uint64_t*)0x200000000108 = -1);
- syscall(__NR_setrlimit, /*res=RLIMIT_FSIZE*/ 1ul,
- /*rlim=*/0x200000000100ul);
- break;
- case 3:
- NONFAILING(memcpy((void*)0x2000000002c0, "./bus\000", 6));
- res = syscall(
- __NR_open, /*file=*/0x2000000002c0ul,
- /*flags=O_SYNC|O_NOCTTY|O_NOATIME|O_CREAT|O_CLOEXEC|0x2*/ 0x1c1142ul,
- /*mode=*/0ul);
- if (res != -1)
- r[0] = res;
- break;
- case 4:
- NONFAILING(memset((void*)0x2000000001c0, 32, 1));
- syscall(__NR_pwrite64, /*fd=*/r[0], /*buf=*/0x2000000001c0ul, /*count=*/1ul,
- /*pos=*/0x4010040bffdul);
- break;
- case 5:
- NONFAILING(memcpy((void*)0x200000000380, "/dev/loop", 9));
- NONFAILING(*(uint8_t*)0x200000000389 = 0x30 + procid * 1);
- NONFAILING(*(uint8_t*)0x20000000038a = 0);
- NONFAILING(memcpy((void*)0x200000000140, "./bus\000", 6));
- syscall(__NR_mount, /*src=*/0x200000000380ul, /*dst=*/0x200000000140ul,
- /*type=*/0ul, /*flags=MS_BIND*/ 0x1000ul, /*data=*/0ul);
- break;
- case 6:
- NONFAILING(memcpy((void*)0x200000000400, "./bus\000", 6));
- res = syscall(__NR_open, /*file=*/0x200000000400ul,
- /*flags=O_SYNC|O_NOCTTY|O_NOATIME|O_RDWR|0x3c*/ 0x14113eul,
- /*mode=*/0ul);
- if (res != -1)
- r[1] = res;
- break;
- case 7:
- res = syscall(__NR_socket, /*domain=*/0xaul, /*type=*/1ul, /*proto=*/0);
- if (res != -1)
- r[2] = res;
- break;
- case 8:
- syscall(__NR_setsockopt, /*fd=*/r[2], /*level=*/6,
- /*optname=TCP_FASTOPEN_NO_COOKIE*/ 0x22, /*optval=*/0ul,
- /*optlen=*/0ul);
- break;
- case 9:
- syscall(__NR_connect, /*fd=*/r[2], /*addr=*/0ul, /*addrlen=*/0ul);
- break;
- case 10:
- NONFAILING(memcpy((void*)0x200000000100, "#! ", 3));
- NONFAILING(*(uint8_t*)0x200000000103 = 0xa);
- syscall(__NR_write, /*fd=*/r[1], /*data=*/0x200000000100ul,
- /*len=*/0x208e24bul);
- break;
- case 11:
- syscall(__NR_close, /*fd=*/4);
- break;
- case 12:
- syscall(__NR_readlink, /*path=*/0ul, /*buf=*/0ul, /*siz=*/0ul);
- break;
- }
- }
- int main(void)
- {
- if (access("/dev/loop0", F_OK) == -1) {
- system("sudo mknod /dev/loop0 b 7 0");
- system("sudo chmod 666 /dev/loop0");
- }
- syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul,
- /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
- /*offset=*/0ul);
- syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*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=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
- /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
- /*offset=*/0ul);
- setup_sysctl();
- const char* reason;
- (void)reason;
- install_segv_handler();
- for (procid = 0; procid < 8; procid++) {
- if (fork() == 0) {
- use_temporary_dir();
- do_sandbox_none();
- }
- }
- sleep(1000000);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement