// https://syzkaller.appspot.com/bug?id=9e3aab774ebecf23a8c45ae16a04fd42c5390460 // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __NR_bpf #define __NR_bpf 321 #endif static unsigned long long procid; 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); } #define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len) \ *(type*)(addr) = \ htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | \ (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) 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 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 struct nlmsg nlmsg; #define WIFI_INITIAL_DEVICE_COUNT 2 #define WIFI_MAC_BASE {0x08, 0x02, 0x11, 0x00, 0x00, 0x00} #define WIFI_IBSS_BSSID {0x50, 0x50, 0x50, 0x50, 0x50, 0x50} #define WIFI_IBSS_SSID {0x10, 0x10, 0x10, 0x10, 0x10, 0x10} #define WIFI_DEFAULT_FREQUENCY 2412 #define WIFI_DEFAULT_SIGNAL 0 #define WIFI_DEFAULT_RX_RATE 1 #define HWSIM_CMD_REGISTER 1 #define HWSIM_CMD_FRAME 2 #define HWSIM_CMD_NEW_RADIO 4 #define HWSIM_ATTR_SUPPORT_P2P_DEVICE 14 #define HWSIM_ATTR_PERM_ADDR 22 #define IF_OPER_UP 6 struct join_ibss_props { int wiphy_freq; bool wiphy_freq_fixed; uint8_t* mac; uint8_t* ssid; int ssid_len; }; static int set_interface_state(const char* interface_name, int on) { struct ifreq ifr; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { return -1; } memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, interface_name); int ret = ioctl(sock, SIOCGIFFLAGS, &ifr); if (ret < 0) { close(sock); return -1; } if (on) ifr.ifr_flags |= IFF_UP; else ifr.ifr_flags &= ~IFF_UP; ret = ioctl(sock, SIOCSIFFLAGS, &ifr); close(sock); if (ret < 0) { return -1; } return 0; } static int nl80211_set_interface(struct nlmsg* nlmsg, int sock, int nl80211_family, uint32_t ifindex, uint32_t iftype, bool dofail) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = NL80211_CMD_SET_INTERFACE; netlink_init(nlmsg, nl80211_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, NL80211_ATTR_IFINDEX, &ifindex, sizeof(ifindex)); netlink_attr(nlmsg, NL80211_ATTR_IFTYPE, &iftype, sizeof(iftype)); int err = netlink_send_ext(nlmsg, sock, 0, NULL, dofail); if (err < 0) { } return err; } static int nl80211_join_ibss(struct nlmsg* nlmsg, int sock, int nl80211_family, uint32_t ifindex, struct join_ibss_props* props, bool dofail) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = NL80211_CMD_JOIN_IBSS; netlink_init(nlmsg, nl80211_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, NL80211_ATTR_IFINDEX, &ifindex, sizeof(ifindex)); netlink_attr(nlmsg, NL80211_ATTR_SSID, props->ssid, props->ssid_len); netlink_attr(nlmsg, NL80211_ATTR_WIPHY_FREQ, &(props->wiphy_freq), sizeof(props->wiphy_freq)); if (props->mac) netlink_attr(nlmsg, NL80211_ATTR_MAC, props->mac, ETH_ALEN); if (props->wiphy_freq_fixed) netlink_attr(nlmsg, NL80211_ATTR_FREQ_FIXED, NULL, 0); int err = netlink_send_ext(nlmsg, sock, 0, NULL, dofail); if (err < 0) { } return err; } static int get_ifla_operstate(struct nlmsg* nlmsg, int ifindex, bool dofail) { struct ifinfomsg info; memset(&info, 0, sizeof(info)); info.ifi_family = AF_UNSPEC; info.ifi_index = ifindex; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sock == -1) { return -1; } netlink_init(nlmsg, RTM_GETLINK, 0, &info, sizeof(info)); int n; int err = netlink_send_ext(nlmsg, sock, RTM_NEWLINK, &n, dofail); close(sock); if (err) { return -1; } struct rtattr* attr = IFLA_RTA(NLMSG_DATA(nlmsg->buf)); for (; RTA_OK(attr, n); attr = RTA_NEXT(attr, n)) { if (attr->rta_type == IFLA_OPERSTATE) return *((int32_t*)RTA_DATA(attr)); } return -1; } static int await_ifla_operstate(struct nlmsg* nlmsg, char* interface, int operstate, bool dofail) { int ifindex = if_nametoindex(interface); while (true) { usleep(1000); int ret = get_ifla_operstate(nlmsg, ifindex, dofail); if (ret < 0) return ret; if (ret == operstate) return 0; } return 0; } static int nl80211_setup_ibss_interface(struct nlmsg* nlmsg, int sock, int nl80211_family_id, char* interface, struct join_ibss_props* ibss_props, bool dofail) { int ifindex = if_nametoindex(interface); if (ifindex == 0) { return -1; } int ret = nl80211_set_interface(nlmsg, sock, nl80211_family_id, ifindex, NL80211_IFTYPE_ADHOC, dofail); if (ret < 0) { return -1; } ret = set_interface_state(interface, 1); if (ret < 0) { return -1; } ret = nl80211_join_ibss(nlmsg, sock, nl80211_family_id, ifindex, ibss_props, dofail); if (ret < 0) { return -1; } return 0; } static int hwsim80211_create_device(struct nlmsg* nlmsg, int sock, int hwsim_family, uint8_t mac_addr[ETH_ALEN]) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = HWSIM_CMD_NEW_RADIO; netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, HWSIM_ATTR_SUPPORT_P2P_DEVICE, NULL, 0); netlink_attr(nlmsg, HWSIM_ATTR_PERM_ADDR, mac_addr, ETH_ALEN); int err = netlink_send(nlmsg, sock); if (err < 0) { } return err; } static void initialize_wifi_devices(void) { int rfkill = open("/dev/rfkill", O_RDWR); if (rfkill == -1) exit(1); struct rfkill_event event = {0}; event.type = RFKILL_TYPE_ALL; event.op = RFKILL_OP_CHANGE_ALL; if (write(rfkill, &event, sizeof(event)) != (ssize_t)(sizeof(event))) exit(1); close(rfkill); uint8_t mac_addr[6] = WIFI_MAC_BASE; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); if (sock < 0) exit(1); int hwsim_family_id = netlink_query_family_id(&nlmsg, sock, "MAC80211_HWSIM", true); int nl80211_family_id = netlink_query_family_id(&nlmsg, sock, "nl80211", true); if (hwsim_family_id < 0 || nl80211_family_id < 0) exit(1); uint8_t ssid[] = WIFI_IBSS_SSID; uint8_t bssid[] = WIFI_IBSS_BSSID; struct join_ibss_props ibss_props = {.wiphy_freq = WIFI_DEFAULT_FREQUENCY, .wiphy_freq_fixed = true, .mac = bssid, .ssid = ssid, .ssid_len = sizeof(ssid)}; for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) { mac_addr[5] = device_id; int ret = hwsim80211_create_device(&nlmsg, sock, hwsim_family_id, mac_addr); if (ret < 0) exit(1); char interface[6] = "wlan0"; interface[4] += device_id; if (nl80211_setup_ibss_interface(&nlmsg, sock, nl80211_family_id, interface, &ibss_props, true) < 0) exit(1); } for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) { char interface[6] = "wlan0"; interface[4] += device_id; int ret = await_ifla_operstate(&nlmsg, interface, IF_OPER_UP, true); if (ret < 0) exit(1); } close(sock); } #define MAX_FDS 30 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(); if (unshare(CLONE_NEWNET)) { } write_file("/proc/sys/net/ipv4/ping_group_range", "0 65535"); initialize_wifi_devices(); 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_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 const char* setup_binfmt_misc() { if (mount(0, "/proc/sys/fs/binfmt_misc", "binfmt_misc", 0, 0) && errno != EBUSY) { return NULL; } if (!write_file("/proc/sys/fs/binfmt_misc/register", ":syz0:M:0:\x01::./file0:") || !write_file("/proc/sys/fs/binfmt_misc/register", ":syz1:M:1:\x02::./file0:POC")) return "write(/proc/sys/fs/binfmt_misc/register) failed"; return NULL; } 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 < 14; 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); event_timedwait(&th->done, 50 + (call == 3 ? 500 : 0) + (call == 4 ? 500 : 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) { int iter = 0; for (;; iter++) { char cwdbuf[32]; sprintf(cwdbuf, "./%d", iter); if (mkdir(cwdbuf, 0777)) exit(1); 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[1] = {0xffffffffffffffff}; void execute_call(int call) { intptr_t res = 0; switch (call) { case 0: // bpf$MAP_CREATE arguments: [ // cmd: const = 0x0 (8 bytes) // arg: ptr[in, bpf_map_create_arg] { // union bpf_map_create_arg { // bloom_filter: // bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], // int32, int32, int32, flags[map_flags, int32], int64[0:15]] { // type: const = 0x1e (4 bytes) // ksize: int32 = 0x9 (4 bytes) // vsize: int32 = 0x0 (4 bytes) // max: int32 = 0xe79d (4 bytes) // flags: map_flags = 0x87106adc4cd9b87f (4 bytes) // inner: fd_bpf_map (resource) // node: int32 = 0xde7 (4 bytes) // map_name: buffer: {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00} (length 0x10) map_ifindex: ifindex (resource) btf_fd: fd_btf // (resource) btf_key_type_id: int32 = 0x4 (4 bytes) // btf_value_type_id: int32 = 0x0 (4 bytes) // btf_vmlinux_type_id: int32 = 0x3 (4 bytes) // map_extra: int64 = 0x4 (8 bytes) // value_type_btf_obj_fd: union // _bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], // int32, int32, int32, flags[map_flags, int32], // int64[0:15]]_value_type_btf_obj_fd_wrapper { // value: fd_btf (resource) // } // pad1: union // _bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], // int32, int32, int32, flags[map_flags, int32], // int64[0:15]]_pad1_wrapper { // void: buffer: {} (length 0x0) // } // map_token_fd: union // _bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], // int32, int32, int32, flags[map_flags, int32], // int64[0:15]]_map_token_fd_wrapper { // value: fd_bpf_token (resource) // } // pad2: union // _bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], // int32, int32, int32, flags[map_flags, int32], // int64[0:15]]_pad2_wrapper { // void: buffer: {} (length 0x0) // } // } // } // } // size: len = 0x50 (8 bytes) // ] // returns fd_bpf_map *(uint32_t*)0x200000000380 = 0x1e; *(uint32_t*)0x200000000384 = 9; *(uint32_t*)0x200000000388 = 0; *(uint32_t*)0x20000000038c = 0xe79d; *(uint32_t*)0x200000000390 = 0x4cd9b87f; *(uint32_t*)0x200000000394 = -1; *(uint32_t*)0x200000000398 = 0xde7; memset((void*)0x20000000039c, 0, 16); *(uint32_t*)0x2000000003ac = 0; *(uint32_t*)0x2000000003b0 = -1; *(uint32_t*)0x2000000003b4 = 4; *(uint32_t*)0x2000000003b8 = 0; *(uint32_t*)0x2000000003bc = 3; *(uint64_t*)0x2000000003c0 = 4; *(uint32_t*)0x2000000003c8 = -1; *(uint32_t*)0x2000000003cc = -1; syscall(__NR_bpf, /*cmd=*/0ul, /*arg=*/0x200000000380ul, /*size=*/0x50ul); break; case 1: // perf_event_open arguments: [ // attr: ptr[in, perf_event_attr] { // perf_event_attr { // type: perf_event_type = 0x1 (4 bytes) // size: len = 0x80 (4 bytes) // config0: int8 = 0x0 (1 bytes) // config1: int8 = 0x0 (1 bytes) // config2: int8 = 0x0 (1 bytes) // config3: int8 = 0x0 (1 bytes) // config4: const = 0x0 (4 bytes) // sample_freq: int64 = 0x5d31 (8 bytes) // sample_type: perf_sample_type = 0x0 (8 bytes) // read_format: perf_read_format = 0x0 (8 bytes) // disabled: int64 = 0x0 (0 bytes) // inherit: int64 = 0x0 (0 bytes) // pinned: int64 = 0x0 (0 bytes) // exclusive: int64 = 0x0 (0 bytes) // exclude_user: int64 = 0x0 (0 bytes) // exclude_kernel: int64 = 0x0 (0 bytes) // exclude_hv: int64 = 0x0 (0 bytes) // exclude_idle: int64 = 0x0 (0 bytes) // mmap: int64 = 0x0 (0 bytes) // comm: int64 = 0x0 (0 bytes) // freq: int64 = 0x0 (0 bytes) // inherit_stat: int64 = 0x0 (0 bytes) // enable_on_exec: int64 = 0x0 (0 bytes) // task: int64 = 0x0 (0 bytes) // watermark: int64 = 0x0 (0 bytes) // precise_ip: int64 = 0x0 (0 bytes) // mmap_data: int64 = 0x0 (0 bytes) // sample_id_all: int64 = 0x0 (0 bytes) // exclude_host: int64 = 0x0 (0 bytes) // exclude_guest: int64 = 0x0 (0 bytes) // exclude_callchain_kernel: int64 = 0x0 (0 bytes) // exclude_callchain_user: int64 = 0x0 (0 bytes) // mmap2: int64 = 0x0 (0 bytes) // comm_exec: int64 = 0x0 (0 bytes) // use_clockid: int64 = 0x0 (0 bytes) // context_switch: int64 = 0x0 (0 bytes) // write_backward: int64 = 0x0 (0 bytes) // namespaces: int64 = 0x0 (0 bytes) // ksymbol: int64 = 0x0 (0 bytes) // bpf_event: int64 = 0x0 (0 bytes) // aux_output: int64 = 0x0 (0 bytes) // cgroup: int64 = 0x0 (0 bytes) // text_poke: int64 = 0x0 (0 bytes) // build_id: int64 = 0x0 (0 bytes) // inherit_thread: int64 = 0x0 (0 bytes) // remove_on_exec: int64 = 0x0 (0 bytes) // sigtrap: int64 = 0x0 (0 bytes) // __reserved_1: const = 0x0 (8 bytes) // wakeup_events: int32 = 0x80 (4 bytes) // bp_type: perf_bp_type = 0x0 (4 bytes) // bp_config: union perf_bp_config { // perf_bp: perf_bp { // bp_addr: nil // bp_len: perf_bp_lens = 0xa (8 bytes) // } // } // branch_sample_type: perf_branch_sample_type = 0x0 (8 bytes) // sample_regs_user: int64 = 0x0 (8 bytes) // sample_stack_user: int32 = 0x1 (4 bytes) // clockid: clock_type = 0x2 (4 bytes) // sample_regs_intr: int64 = 0x0 (8 bytes) // aux_watermark: int32 = 0x0 (4 bytes) // sample_max_stack: int16 = 0x0 (2 bytes) // __reserved_2: const = 0x0 (2 bytes) // aux_sample_size: int32 = 0x0 (4 bytes) // __reserved_3: const = 0x0 (4 bytes) // sig_data: int64 = 0x0 (8 bytes) // } // } // pid: pid (resource) // cpu: intptr = 0xffffffffffffffff (8 bytes) // group: fd_perf (resource) // flags: perf_flags = 0x0 (8 bytes) // ] // returns fd_perf *(uint32_t*)0x200000000480 = 1; *(uint32_t*)0x200000000484 = 0x80; *(uint8_t*)0x200000000488 = 0; *(uint8_t*)0x200000000489 = 0; *(uint8_t*)0x20000000048a = 0; *(uint8_t*)0x20000000048b = 0; *(uint32_t*)0x20000000048c = 0; *(uint64_t*)0x200000000490 = 0x5d31; *(uint64_t*)0x200000000498 = 0; *(uint64_t*)0x2000000004a0 = 0; STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 0, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 1, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 2, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 3, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 4, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 5, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 6, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 7, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 8, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 9, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 10, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 11, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 12, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 13, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 14, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 15, 2); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 17, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 18, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 19, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 20, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 21, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 22, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 23, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 24, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 25, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 26, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 27, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 28, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 29, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 30, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 31, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 32, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 33, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 34, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 35, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 36, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 37, 1); STORE_BY_BITMASK(uint64_t, , 0x2000000004a8, 0, 38, 26); *(uint32_t*)0x2000000004b0 = 0x80; *(uint32_t*)0x2000000004b4 = 0; *(uint64_t*)0x2000000004b8 = 0; *(uint64_t*)0x2000000004c0 = 0xa; *(uint64_t*)0x2000000004c8 = 0; *(uint64_t*)0x2000000004d0 = 0; *(uint32_t*)0x2000000004d8 = 1; *(uint32_t*)0x2000000004dc = 2; *(uint64_t*)0x2000000004e0 = 0; *(uint32_t*)0x2000000004e8 = 0; *(uint16_t*)0x2000000004ec = 0; *(uint16_t*)0x2000000004ee = 0; *(uint32_t*)0x2000000004f0 = 0; *(uint32_t*)0x2000000004f4 = 0; *(uint64_t*)0x2000000004f8 = 0; syscall(__NR_perf_event_open, /*attr=*/0x200000000480ul, /*pid=*/0, /*cpu=*/(intptr_t)-1, /*group=*/(intptr_t)-1, /*flags=*/0ul); break; case 2: // perf_event_open arguments: [ // attr: nil // pid: pid (resource) // cpu: intptr = 0xffffffffffffffff (8 bytes) // group: fd_perf (resource) // flags: perf_flags = 0x0 (8 bytes) // ] // returns fd_perf syscall(__NR_perf_event_open, /*attr=*/0ul, /*pid=*/0, /*cpu=*/(intptr_t)-1, /*group=*/(intptr_t)-1, /*flags=*/0ul); break; case 3: // bpf$BPF_PROG_RAW_TRACEPOINT_LOAD arguments: [ // cmd: const = 0x5 (8 bytes) // arg: ptr[in, bpf_prog_t[flags[bpf_raw_tracepoint_prog_types, int32], // const[0, int32], const[0, int32], const[0, int32]]] { // bpf_prog_t[flags[bpf_raw_tracepoint_prog_types, int32], const[0, // int32], const[0, int32], const[0, int32]] { // type: bpf_raw_tracepoint_prog_types = 0x10 (4 bytes) // ninsn: bytesize8 = 0x3 (4 bytes) // insns: ptr[inout, array[ANYUNION]] { // array[ANYUNION] { // union ANYUNION { // ANYBLOB: buffer: {62 0a c4 ff 00 00 00 00 71 10 17 00 00 00 // 00 00 95 00 00 00 00 00 00 00 4e d7 e3 29 03 09 00 00 00 00 // 00 00 00 38 b9 38 3b 4d ec c7 1d 6d c4 66 08 40 0d 74 e7 b5 // c3 a7 04 b2 ed 9e eb 0b d5 7e 5b 79 67 71 26 5d a7 d1 3c 6a // ab e9 ea a8 55 c2 6e ef 14 22 39 34 25 82 02} (length 0x59) // } // } // } // license: nil // loglev: int32 = 0x0 (4 bytes) // logsize: len = 0x0 (4 bytes) // log: nil // kern_version: bpf_kern_version = 0x0 (4 bytes) // flags: bpf_prog_load_flags = 0x0 (4 bytes) // prog_name: buffer: {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00} (length 0x10) prog_ifindex: ifindex (resource) // expected_attach_type: const = 0x0 (4 bytes) // btf_fd: fd_btf (resource) // func_info_rec_size: const = 0x8 (4 bytes) // func_info: nil // func_info_cnt: len = 0x0 (4 bytes) // line_info_rec_size: const = 0x10 (4 bytes) // line_info: nil // line_info_cnt: len = 0x0 (4 bytes) // attach_btf_id: const = 0x0 (4 bytes) // attach_prog_fd: const = 0x0 (4 bytes) // core_relo_cnt: len = 0x0 (4 bytes) // fd_array: nil // core_relos: nil // core_relo_rec_size: const = 0x10 (4 bytes) // log_true_size: int32 = 0x0 (4 bytes) // prog_token_fd: union // _bpf_prog_t[flags[bpf_raw_tracepoint_prog_types, int32], const[0, // int32], const[0, int32], const[0, int32]]_prog_token_fd_wrapper { // void: buffer: {} (length 0x0) // } // pad: union _bpf_prog_t[flags[bpf_raw_tracepoint_prog_types, // int32], const[0, int32], const[0, int32], const[0, // int32]]_pad_wrapper { // value: const = 0x0 (4 bytes) // } // } // } // size: len = 0x94 (8 bytes) // ] // returns fd_bpf_prog_raw_tracepoint *(uint32_t*)0x200000000600 = 0x10; *(uint32_t*)0x200000000604 = 3; *(uint64_t*)0x200000000608 = 0x2000000006c0; memcpy((void*)0x2000000006c0, "\x62\x0a\xc4\xff\x00\x00\x00\x00\x71\x10\x17\x00\x00\x00\x00\x00" "\x95\x00\x00\x00\x00\x00\x00\x00\x4e\xd7\xe3\x29\x03\x09\x00\x00" "\x00\x00\x00\x00\x00\x38\xb9\x38\x3b\x4d\xec\xc7\x1d\x6d\xc4\x66" "\x08\x40\x0d\x74\xe7\xb5\xc3\xa7\x04\xb2\xed\x9e\xeb\x0b\xd5\x7e" "\x5b\x79\x67\x71\x26\x5d\xa7\xd1\x3c\x6a\xab\xe9\xea\xa8\x55\xc2" "\x6e\xef\x14\x22\x39\x34\x25\x82\x02", 89); *(uint64_t*)0x200000000610 = 0; *(uint32_t*)0x200000000618 = 0; *(uint32_t*)0x20000000061c = 0; *(uint64_t*)0x200000000620 = 0; *(uint32_t*)0x200000000628 = 0; *(uint32_t*)0x20000000062c = 0; memset((void*)0x200000000630, 0, 16); *(uint32_t*)0x200000000640 = 0; *(uint32_t*)0x200000000644 = 0; *(uint32_t*)0x200000000648 = -1; *(uint32_t*)0x20000000064c = 8; *(uint64_t*)0x200000000650 = 0; *(uint32_t*)0x200000000658 = 0; *(uint32_t*)0x20000000065c = 0x10; *(uint64_t*)0x200000000660 = 0; *(uint32_t*)0x200000000668 = 0; *(uint32_t*)0x20000000066c = 0; *(uint32_t*)0x200000000670 = 0; *(uint32_t*)0x200000000674 = 0; *(uint64_t*)0x200000000678 = 0; *(uint64_t*)0x200000000680 = 0; *(uint32_t*)0x200000000688 = 0x10; *(uint32_t*)0x20000000068c = 0; *(uint32_t*)0x200000000690 = 0; syscall(__NR_bpf, /*cmd=*/5ul, /*arg=*/0x200000000600ul, /*size=*/0x94ul); break; case 4: // bpf$BPF_RAW_TRACEPOINT_OPEN arguments: [ // cmd: const = 0x11 (8 bytes) // arg: ptr[in, bpf_raw_tracepoint] { // bpf_raw_tracepoint { // name: ptr[in, buffer] { // buffer: {73 79 73 5f 65 6e 74 65 72 00} (length 0xa) // } // prog_fd: fd_bpf_prog_raw_tracepoint (resource) // pad: const = 0x0 (4 bytes) // cookie: int64 = 0x0 (8 bytes) // } // } // size: len = 0x10 (8 bytes) // ] // returns fd_perf_base *(uint64_t*)0x200000000600 = 0x2000000005c0; memcpy((void*)0x2000000005c0, "sys_enter\000", 10); *(uint32_t*)0x200000000608 = -1; *(uint32_t*)0x20000000060c = 0; *(uint64_t*)0x200000000610 = 0; syscall(__NR_bpf, /*cmd=*/0x11ul, /*arg=*/0x200000000600ul, /*size=*/0x10ul); break; case 5: // perf_event_open arguments: [ // attr: nil // pid: pid (resource) // cpu: intptr = 0xaffffffefffffffe (8 bytes) // group: fd_perf (resource) // flags: perf_flags = 0x0 (8 bytes) // ] // returns fd_perf syscall(__NR_perf_event_open, /*attr=*/0ul, /*pid=*/0, /*cpu=*/0xaffffffefffffffeul, /*group=*/(intptr_t)-1, /*flags=*/0ul); break; case 6: // bpf$PROG_LOAD arguments: [ // cmd: const = 0x5 (8 bytes) // arg: nil // size: len = 0x0 (8 bytes) // ] // returns fd_bpf_prog syscall(__NR_bpf, /*cmd=*/5ul, /*arg=*/0ul, /*size=*/0ul); break; case 7: // recvmsg$kcm arguments: [ // fd: sock_kcm (resource) // msg: nil // f: recv_flags = 0x12100 (8 bytes) // ] syscall(__NR_recvmsg, /*fd=*/(intptr_t)-1, /*msg=*/0ul, /*f=MSG_WAITFORONE|MSG_WAITALL|MSG_ERRQUEUE*/ 0x12100ul, 0); break; case 8: // perf_event_open arguments: [ // attr: ptr[in, perf_event_attr] { // perf_event_attr { // type: perf_event_type = 0x2 (4 bytes) // size: len = 0x80 (4 bytes) // config0: int8 = 0xec (1 bytes) // config1: int8 = 0x0 (1 bytes) // config2: int8 = 0x0 (1 bytes) // config3: int8 = 0x0 (1 bytes) // config4: const = 0x0 (4 bytes) // sample_freq: int64 = 0x0 (8 bytes) // sample_type: perf_sample_type = 0x0 (8 bytes) // read_format: perf_read_format = 0x0 (8 bytes) // disabled: int64 = 0x0 (0 bytes) // inherit: int64 = 0x0 (0 bytes) // pinned: int64 = 0x0 (0 bytes) // exclusive: int64 = 0x0 (0 bytes) // exclude_user: int64 = 0x0 (0 bytes) // exclude_kernel: int64 = 0x0 (0 bytes) // exclude_hv: int64 = 0x0 (0 bytes) // exclude_idle: int64 = 0x0 (0 bytes) // mmap: int64 = 0x0 (0 bytes) // comm: int64 = 0x0 (0 bytes) // freq: int64 = 0x0 (0 bytes) // inherit_stat: int64 = 0x0 (0 bytes) // enable_on_exec: int64 = 0x0 (0 bytes) // task: int64 = 0x0 (0 bytes) // watermark: int64 = 0x0 (0 bytes) // precise_ip: int64 = 0x0 (0 bytes) // mmap_data: int64 = 0x0 (0 bytes) // sample_id_all: int64 = 0x0 (0 bytes) // exclude_host: int64 = 0x0 (0 bytes) // exclude_guest: int64 = 0x0 (0 bytes) // exclude_callchain_kernel: int64 = 0x0 (0 bytes) // exclude_callchain_user: int64 = 0x0 (0 bytes) // mmap2: int64 = 0x0 (0 bytes) // comm_exec: int64 = 0x0 (0 bytes) // use_clockid: int64 = 0x0 (0 bytes) // context_switch: int64 = 0x0 (0 bytes) // write_backward: int64 = 0x0 (0 bytes) // namespaces: int64 = 0x0 (0 bytes) // ksymbol: int64 = 0x0 (0 bytes) // bpf_event: int64 = 0x0 (0 bytes) // aux_output: int64 = 0x0 (0 bytes) // cgroup: int64 = 0x0 (0 bytes) // text_poke: int64 = 0x0 (0 bytes) // build_id: int64 = 0x0 (0 bytes) // inherit_thread: int64 = 0x0 (0 bytes) // remove_on_exec: int64 = 0x0 (0 bytes) // sigtrap: int64 = 0x0 (0 bytes) // __reserved_1: const = 0x0 (8 bytes) // wakeup_events: int32 = 0x0 (4 bytes) // bp_type: perf_bp_type = 0x0 (4 bytes) // bp_config: union perf_bp_config { // perf_bp: perf_bp { // bp_addr: nil // bp_len: perf_bp_lens = 0xa (8 bytes) // } // } // branch_sample_type: perf_branch_sample_type = 0x114905 (8 bytes) // sample_regs_user: int64 = 0x4 (8 bytes) // sample_stack_user: int32 = 0x0 (4 bytes) // clockid: clock_type = 0x1 (4 bytes) // sample_regs_intr: int64 = 0x0 (8 bytes) // aux_watermark: int32 = 0x0 (4 bytes) // sample_max_stack: int16 = 0x1 (2 bytes) // __reserved_2: const = 0x0 (2 bytes) // aux_sample_size: int32 = 0x0 (4 bytes) // __reserved_3: const = 0x0 (4 bytes) // sig_data: int64 = 0x0 (8 bytes) // } // } // pid: pid (resource) // cpu: intptr = 0x1 (8 bytes) // group: fd_perf (resource) // flags: perf_flags = 0x0 (8 bytes) // ] // returns fd_perf *(uint32_t*)0x200000000040 = 2; *(uint32_t*)0x200000000044 = 0x80; *(uint8_t*)0x200000000048 = 0xec; *(uint8_t*)0x200000000049 = 0; *(uint8_t*)0x20000000004a = 0; *(uint8_t*)0x20000000004b = 0; *(uint32_t*)0x20000000004c = 0; *(uint64_t*)0x200000000050 = 0; *(uint64_t*)0x200000000058 = 0; *(uint64_t*)0x200000000060 = 0; STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 0, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 1, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 2, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 3, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 4, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 5, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 6, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 7, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 8, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 9, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 10, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 11, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 12, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 13, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 14, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 15, 2); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 17, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 18, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 19, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 20, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 21, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 22, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 23, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 24, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 25, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 26, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 27, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 28, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 29, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 30, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 31, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 32, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 33, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 34, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 35, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 36, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 37, 1); STORE_BY_BITMASK(uint64_t, , 0x200000000068, 0, 38, 26); *(uint32_t*)0x200000000070 = 0; *(uint32_t*)0x200000000074 = 0; *(uint64_t*)0x200000000078 = 0; *(uint64_t*)0x200000000080 = 0xa; *(uint64_t*)0x200000000088 = 0x114905; *(uint64_t*)0x200000000090 = 4; *(uint32_t*)0x200000000098 = 0; *(uint32_t*)0x20000000009c = 1; *(uint64_t*)0x2000000000a0 = 0; *(uint32_t*)0x2000000000a8 = 0; *(uint16_t*)0x2000000000ac = 1; *(uint16_t*)0x2000000000ae = 0; *(uint32_t*)0x2000000000b0 = 0; *(uint32_t*)0x2000000000b4 = 0; *(uint64_t*)0x2000000000b8 = 0; syscall(__NR_perf_event_open, /*attr=*/0x200000000040ul, /*pid=*/0, /*cpu=*/1ul, /*group=*/(intptr_t)-1, /*flags=*/0ul); break; case 9: // openat$cgroup_ro arguments: [ // fd: fd_cgroup (resource) // file: ptr[in, buffer] { // buffer: {63 70 75 61 63 63 74 2e 73 74 61 74 00} (length 0xd) // } // flags: const = 0x26e1 (4 bytes) // mode: const = 0x0 (2 bytes) // ] // returns fd memcpy((void*)0x200000000400, "cpuacct.stat\000", 13); res = syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000400ul, /*flags=*/0x26e1, /*mode=*/0); if (res != -1) r[0] = res; break; case 10: // close arguments: [ // fd: fd (resource) // ] syscall(__NR_close, /*fd=*/r[0]); break; case 11: // socketpair arguments: [ // domain: socket_domain = 0x1 (8 bytes) // type: socket_type = 0x20000000000001 (8 bytes) // proto: int32 = 0x0 (4 bytes) // fds: ptr[out, sock_pair] { // sock_pair { // fd0: sock (resource) // fd1: sock (resource) // } // } // ] syscall(__NR_socketpair, /*domain=AF_UNIX*/ 1ul, /*type=SOCK_STREAM|0x20000000000000*/ 0x20000000000001ul, /*proto=*/0, /*fds=*/0x2000000006c0ul); break; case 12: // ioctl$PERF_EVENT_IOC_SET_FILTER arguments: [ // fd: fd_perf (resource) // cmd: const = 0x8948 (4 bytes) // filter: ptr[in, buffer] { // buffer: {6c 6f 3a 96 6f 38 14 64 a1 e3 d7 5c 62 7d 1f a1 59 ad 34 00 // 20 27 59 17 5d 15 63 ca 52 dd 98 4f 47 4b ff e6 84 e2 05 80 77 d2 7c // 44 8d 4b 14 42 78 cb 75 48 c2 ee 63 bf 3c 3e 59 1a fc 1f 39 4f 42 81 // 89 b7 6c ed 7d e5 18 36 c5 71 40 6e b4 b7 73 b0 00 00 00 00 f5 07 00 // 00 da ef ec 45 ec d5 49 b2 9b fe 8d 90 3f 00 e9 e4 7e 67 3a c1 b2 61 // 6b 96 bb a7 e2 c0 dc f9 51 08 eb 01 00 00 00 d3 0d 37 8e ab 64 0f 74 // 70 82 ae d2 15 8e 2b 63 f6 bf e1 34 3e a6 2d a5 63 de d7 ab ea 1f d5 // 73 32 9c 56 46 d5 18 fe 0f 8f 20 01 00 00 b1 88 eb 57 5f a5 e1 f6 8a // 6a ca f8 6d ab e8 99 eb 77 23 8a 74 1c 80 fc b0 95 a2 a7 d7 2c 59 5d // 45 38 83 58 f5 46 dc 88 2d f5 b0 b5 5e db 1a b6 aa 14 e2 0d 68 5e 4a // 2d d1 ba 55 6e 04 27 35 1c b5 bf b6 90 b4 c2 7f 5d 2f b3 e7 c9 27 94 // cf 49 6f df 04 95 b5 06 84 1f 48 3e d9 99 2d 1b 7c 47 8d d4 b9 25 aa // 51 a0 4b 10 1f 9c 2c 11 33 7f 03 93 e1 cc e7 66 0d f3 ff 30 0c 82 25 // 5f 92 8b c4 b9 d9 e7 f2 e4 c1 69 03 9d dd 1b 6a df ac 67 e3 a0 52 d3 // 8a e1 6e 97 ea f1 a0 27 0b e9 a0 f1 20 66 aa 6e cf b5 69 b6 64 bc 92 // 0b d5 38 16 08 b3 5f 3a a4 21 0a 79 c4 26 0a 57 4d 4d a8 c4 0b 9f 01 // 6f f4 ab 26 b6 17 02 50 c3 21 4e a1 86 0d d7 04 f1 c0 21 ed ff ee 24 // c8 39 8c 42 01 d1 a8 d4 e6 4b 30 e1 a3 54 53 18 e6 78 1f 25 50 9f 55 // 29 83 45 0a 90 4d 0d 2e 85 67 6e 5f b2 e9 8a 1c e3 93 d8 bc b6 4e c3 // e1 af 68 a0 69 46 dc 71 f9 17 d9 69 84 34 45 1a 13 9a e6 d3 ab 3a 50 // 4d fb 65 fe 39 d9 94 1d 78 d6 09 62 f7 10 4e d1 93 0d 55 7f 79 18 74 // 45 f1 2a 9a 30 5a 9f dc 7b 13 f6 b7 f7 e6 3d 9c 44 10 38 8e 53 a0 d0 // a7 09 6e d9 ae c0 18 00 08 00 00 59 b2 82 77 15 30 97 ba e6 ca b1 a3 // 02 14 5e bd 5a ae f5 2f cf b8 ea 38 55 77 92 60 22 32 81 6a bb 87 2b // 89 c5 3c 4a 1f ba fc 90 28 98 35 93 a8 d4 f0 bd 54 79 18 c8 a0 bb 99 // 8c e0 51 ff 43 6c bd 58 7e 33 a1 a2 f4 d9 f7 c7 fb ce 95 39 78 fe 57 // 0d f0 7b ca 54 ec 70 29 3d 9d df 47 38 bf e3 3f 64 3c 4a 4e cb d4 48 // b0 5f 6a 4f f3 90 e8 2f 6c df 67 29 8d 23 fd 6f a9 4c de 41 2a ec a1 // 14 2c e8 8d 5e b9 72 3d c0 18 d4 11 64 55 5b 52 79 ed d6 97 8a e8 ca // 99 10 8e c8 50 a3 ae 2f da 6f 66 06 7f f7 80 24 66 08 92 ae eb dd 22 // 89 b8 f0 c3 08 00 00 00 00 0c 72 f1 ec d9 43 44 80 b4 5e 8c 77 3b 87 // ea 8c 8b 4a 9a 0e 6a 8f 8e 5e e6 a6 aa 91 30 0c 44 ab 46 55 a0 44 3b // d6 d1 ee 72 9d 02 d9 f7 64 60 bf 76 15 2e e4 82 7c 29 4b 99 98 26 3f // cd e5 a8 ba 7e 24 3b 67 09 02 84 2b 90 ab 81 36 24 2f 92 22 ef f7 18 // fa 45 fe f7 0a b2 7f 43 bb bd 67 23 46 0a 0b 75 e2 e9 08 a2 f1 94 46 // 62 92 c9 dd 50 f0 6d 33 35 2b dd ac 33 00 dd fb 08 c0 95 e8 a5 ec 9e // bf 41 7f ff b8 e2 e2 48 4e 79 24 d4 c6 9d 64 09 f6 ed 10 15 25 0d 1a // 44 0c 3e dc 5a b9 d7 5a 88 9b df 66 5b 90 fa 9a 7b 62 f4 44 71} // (length 0x365) // } // ] memcpy( (void*)0x200000000000, "lo:\226o8\024d\241\343\327\\b}\037\241Y\2554\000 " "\'Y\027]\025c\312R\335\230OGK\377\346\204\342\005\200w\322|" "D\215K\024Bx\313uH\302\356c\277<>Y\032\374\0379OB\201\211\267l\355}" "\345\0306\305q@" "n\264\267s\260\000\000\000\000\365\a\000\000\332\357\354E\354\325I\262" "\233\376\215\220?\000\351\344~g:" "\301\262ak\226\273\247\342\300\334\371Q\b\353\001\000\000\000\323\r7" "\216\253d\017tp\202\256\322\025\216+c\366\277\3414>\246-" "\245c\336\327\253\352\037\325s2\234VF\325\030\376\017\217 " "\001\000\000\261\210\353W_\245\341\366\212j\312\370m\253\350\231\353w#" "\212t\034\200\374\260\225\242\247\327,Y]E8\203X\365F\334\210-" "\365\260\265^\333\032\266\252\024\342\rh^J-" "\321\272Un\004\'5\034\265\277\266\220\264\302\177]/" "\263\347\311\'\224\317Io\337\004\225\265\006\204\037H>\331\231-\033|" "G\215\324\271%\252Q\240K\020\037\234," "\0213\177\003\223\341\314\347f\r\363\3770\f\202%_" "\222\213\304\271\331\347\362\344\301i\003\235\335\033j\337\254g\343" "\240R\323\212\341n\227\352\361\240\'\v\351\240\361 " "f\252n\317\265i\266d\274\222\v\3258\026\b\263_:\244!\ny\304&" "\nWMM\250\304\v\237\001o\364\253&\266\027\002P\303!" "N\241\206\r\327\004\361\300!\355\377\356$" "\3109\214B\001\321\250\324\346K0\341\243TS\030\346x\037%P\237U)" "\203E\n\220M\r.\205gn_" "\262\351\212\034\343\223\330\274\266N\303\341\257h\240iF\334q\371\027" "\331i\2044E\032\023\232\346\323\253:" "PM\373e\3769\331\224\035x\326\tb\367\020N\321\223\rU\177y\030tE\361*" "\2320Z\237\334{\023\366\267\367\346=" "\234D\0208\216S\240\320\247\tn\331\256\300\030\000\b\000\000Y\262\202w" "\0250\227\272\346\312\261\243\002\024^\275Z\256\365/" "\317\270\3528Uw\222`\"2\201j\273\207+\211\305" "\334Z\271\327Z\210\233\337f[\220\372\232{b\364Dq", 869); syscall(__NR_ioctl, /*fd=*/(intptr_t)-1, /*cmd=*/0x8948, /*filter=*/0x200000000000ul); break; case 13: // ioctl$SIOCSIFHWADDR arguments: [ // fd: fd_tun (resource) // cmd: const = 0x8b28 (4 bytes) // arg: ptr[in, ifreq_dev_t[devnames, mac_addr]] { // ifreq_dev_t[devnames, mac_addr] { // ifr_ifrn: buffer: {77 6c 61 6e 31 00 00 00 00 00 00 00 00 00 00 // 00} (length 0x10) elem: union mac_addr { // random: buffer: {01 00 00 00 00 00} (length 0x6) // } // pad = 0x0 (18 bytes) // } // } // ] memcpy((void*)0x200000000000, "wlan1\000\000\000\000\000\000\000\000\000\000\000", 16); memcpy((void*)0x200000000010, "\x01\x00\x00\x00\x00\x00", 6); syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x8b28, /*arg=*/0x200000000000ul); break; } } int main(void) { syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-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=*/(intptr_t)-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); const char* reason; (void)reason; if ((reason = setup_binfmt_misc())) printf("the reproducer may not work as expected: binfmt_misc setup failed: " "%s\n", reason); for (procid = 0; procid < 4; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; }