lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+-ZZ_igYSw1=563skeb-e5+YiN81KHtjmYGZ7bvBK4h3piZ9g@mail.gmail.com>
Date: Mon, 6 Jan 2025 21:32:08 -0500
From: reveliofuzzing <reveliofuzzing@...il.com>
To: tglx@...utronix.de, mingo@...hat.com, bp@...en8.de, 
	dave.hansen@...ux.intel.com, kirill.shutemov@...ux.intel.com
Cc: x86@...nel.org, linux-kernel@...r.kernel.org
Subject: reproducible GPF error in native_tss_update_io_bitmap

Hello,

We found the following general protection fault bug in Linux kernel 6.12, and
it can be reproduced stably in a QEMU VM. To our knowledge, this problem has not
been observed by SyzBot so we would like to report it for your reference.

- dmesg
syzkaller login: [   90.849309] Oops: general protection fault,
probably for non-canonical address 0xdffffc0000000000: 0000 [#1]
PREEMPTI
[   90.853735] KASAN: null-ptr-deref in range
[0x0000000000000000-0x0000000000000007]
[   90.856772] CPU: 0 PID: 3265 Comm: iou-sqp-3264 Not tainted 6.10.0 #2
[   90.859386] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS 1.13.0-1ubuntu1.1 04/01/2014
[   90.862774] RIP: 0010:native_tss_update_io_bitmap+0x143/0x510
[   90.865203] Code: 00 fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f
85 ae 03 00 00 48 89 da 4d 8b 75 68 48 b8 00 00 00 00 00 fc ff df 4c
[   90.872684] RSP: 0018:ffff8880079776c0 EFLAGS: 00010246
[   90.875623] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff810a7045
[   90.878708] RDX: 0000000000000000 RSI: ffffffff810a70a6 RDI: ffff88806d20a068
[   90.881705] RBP: ffff888007977740 R08: ffffffff8171dc14 R09: ffffed10014763c1
[   90.884683] R10: ffffed10014763c0 R11: ffff88800a3b1e07 R12: 1ffff11000f2eed8
[   90.887673] R13: ffff88806d20a000 R14: 00000000000005d4 R15: ffff888007977950
[   90.890639] FS:  000055557b069940(0000) GS:ffff88806d200000(0000)
knlGS:0000000000000000
[   90.894196] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   90.896589] CR2: 0000000000004028 CR3: 000000000bf84000 CR4: 00000000000006f0
[   90.899520] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   90.902247] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   90.904931] Call Trace:
[   90.905938]  <TASK>
[   90.906804]  ? show_regs+0x73/0x80
[   90.908166]  ? __die_body+0x1f/0x70
[   90.909495]  ? die_addr+0x4c/0x90
[   90.910773]  ? exc_general_protection+0x15c/0x2a0
[   90.912665]  ? asm_exc_general_protection+0x26/0x30
[   90.914566]  ? kasan_save_stack+0x24/0x50
[   90.916239]  ? native_tss_update_io_bitmap+0x85/0x510
[   90.918173]  ? native_tss_update_io_bitmap+0xe6/0x510
[   90.920145]  ? native_tss_update_io_bitmap+0x143/0x510
[   90.922509]  ? __pfx_native_tss_update_io_bitmap+0x10/0x10
[   90.925039]  ? __pfx_refcount_dec_not_one+0x10/0x10
[   90.927396]  ? __virt_addr_valid+0xcb/0x320
[   90.929218]  ? __pfx_delayed_put_pid+0x10/0x10
[   90.930957]  task_update_io_bitmap+0xa2/0xd0
[   90.932599]  io_bitmap_exit+0x4d/0xd0
[   90.933995]  exit_thread+0x6b/0x80
[   90.935319]  copy_process+0x480f/0x6540
[   90.936878]  ? __pfx_copy_process+0x10/0x10
[   90.938857]  ? _raw_spin_lock_irqsave+0x86/0xe0
[   90.940957]  ? try_to_wake_up+0x117/0x18a0
[   90.942490]  ? __pfx_io_wq_worker+0x10/0x10
[   90.944116]  create_io_thread+0xac/0xf0
[   90.945578]  ? __pfx_create_io_thread+0x10/0x10
[   90.947344]  ? __pfx_io_wq_worker+0x10/0x10
[   90.948935]  ? kasan_save_track+0x14/0x30
[   90.950458]  create_io_worker+0x17e/0x4c0
[   90.952015]  io_wq_enqueue+0x5a1/0x990
[   90.953427]  ? __pfx_io_wq_enqueue+0x10/0x10
[   90.955081]  ? __pfx__raw_spin_lock+0x10/0x10
[   90.957061]  ? __pfx_io_wq_work_match_item+0x10/0x10
[   90.958969]  io_queue_iowq+0x1c4/0x380
[   90.960413]  io_queue_sqe_fallback+0xa4/0x790
[   90.962097]  io_submit_sqes+0x1232/0x1e80
[   90.963627]  io_sq_thread+0xaf9/0x1620
[   90.965272]  ? __pfx_io_sq_thread+0x10/0x10
[   90.966960]  ? __pfx_autoremove_wake_function+0x10/0x10
[   90.969010]  ? _raw_spin_lock_irq+0x81/0xe0
[   90.970775]  ? finish_task_switch+0x1bd/0x650
[   90.972809]  ? __pfx_io_sq_thread+0x10/0x10
[   90.974572]  ? __pfx_io_sq_thread+0x10/0x10
[   90.976372]  ret_from_fork+0x48/0x80
[   90.977916]  ? __pfx_io_sq_thread+0x10/0x10
[   90.979704]  ret_from_fork_asm+0x1a/0x30
[   90.981443]  </TASK>
[   90.982411] Modules linked in:
[   90.984086] ---[ end trace 0000000000000000 ]---
[   90.986042] RIP: 0010:native_tss_update_io_bitmap+0x143/0x510
[   90.989080] Code: 00 fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f
85 ae 03 00 00 48 89 da 4d 8b 75 68 48 b8 00 00 00 00 00 fc ff df 4c
[   90.997385] RSP: 0018:ffff8880079776c0 EFLAGS: 00010246
[   91.000093] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff810a7045
[   91.003230] RDX: 0000000000000000 RSI: ffffffff810a70a6 RDI: ffff88806d20a068
[   91.006468] RBP: ffff888007977740 R08: ffffffff8171dc14 R09: ffffed10014763c1
[   91.010241] R10: ffffed10014763c0 R11: ffff88800a3b1e07 R12: 1ffff11000f2eed8
[   91.014085] R13: ffff88806d20a000 R14: 00000000000005d4 R15: ffff888007977950
[   91.017484] FS:  000055557b069940(0000) GS:ffff88806d200000(0000)
knlGS:0000000000000000
[   91.020992] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   91.023575] CR2: 0000000000004028 CR3: 000000000bf84000 CR4: 00000000000006f0
[   91.026987] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   91.030017] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   91.033300] note: iou-sqp-3264[3265] exited with preempt_count 1

- kernel config
https://drive.google.com/file/d/1ZfeXgVadChVJtIGx5zMhBqHnmlomP3Hf/view?usp=sharing

- bzImage
https://drive.google.com/file/d/1MJf0WQ9_eztvuBcaBwCGC-rb7VBQtuac/view?usp=sharing

- reproducer (compiled binary)
https://drive.google.com/file/d/1KTq0f4yY8kKsUKY8b_6q5u8TeEGvW95B/view?usp=sharing

- steps to reproduce
    1. Create the VM image
    We use the script
https://github.com/google/syzkaller/blob/master/tools/create-image.sh
    to create the image.
    2. Run the VM
    We run command: qemu-system-x86_64 -m 2G -smp 4 -kernel bzImage \
    -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
    -drive file=./bullseye.img,format=raw \
    -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
    -net nic,model=e1000 \
    -enable-kvm \
    -nographic \
    -pidfile vm.pid \
    2>&1 | tee vm.log`
    3. Run the reproducer
    We ssh into the VM and run the compiled binary `syz-executor` under root.
    This error might take a few minutes to happen.

- reproducer (c)
// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE

#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include <linux/capability.h>

#ifndef __NR_io_uring_setup
#define __NR_io_uring_setup 425
#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 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;
}

#define SIZEOF_IO_URING_SQE 64
#define SIZEOF_IO_URING_CQE 16
#define SQ_HEAD_OFFSET 0
#define SQ_TAIL_OFFSET 64
#define SQ_RING_MASK_OFFSET 256
#define SQ_RING_ENTRIES_OFFSET 264
#define SQ_FLAGS_OFFSET 276
#define SQ_DROPPED_OFFSET 272
#define CQ_HEAD_OFFSET 128
#define CQ_TAIL_OFFSET 192
#define CQ_RING_MASK_OFFSET 260
#define CQ_RING_ENTRIES_OFFSET 268
#define CQ_RING_OVERFLOW_OFFSET 284
#define CQ_FLAGS_OFFSET 280
#define CQ_CQES_OFFSET 320

struct io_sqring_offsets {
        uint32_t head;
        uint32_t tail;
        uint32_t ring_mask;
        uint32_t ring_entries;
        uint32_t flags;
        uint32_t dropped;
        uint32_t array;
        uint32_t resv1;
        uint64_t resv2;
};

struct io_cqring_offsets {
        uint32_t head;
        uint32_t tail;
        uint32_t ring_mask;
        uint32_t ring_entries;
        uint32_t overflow;
        uint32_t cqes;
        uint64_t resv[2];
};

struct io_uring_params {
        uint32_t sq_entries;
        uint32_t cq_entries;
        uint32_t flags;
        uint32_t sq_thread_cpu;
        uint32_t sq_thread_idle;
        uint32_t features;
        uint32_t resv[4];
        struct io_sqring_offsets sq_off;
        struct io_cqring_offsets cq_off;
};

#define IORING_OFF_SQ_RING 0
#define IORING_OFF_SQES 0x10000000ULL
#define IORING_SETUP_SQE128 (1U << 10)
#define IORING_SETUP_CQE32 (1U << 11)

static long syz_io_uring_setup(volatile long a0, volatile long a1,
volatile long a2, volatile long a3)
{
        uint32_t entries = (uint32_t)a0;
        struct io_uring_params* setup_params = (struct io_uring_params*)a1;
        void** ring_ptr_out = (void**)a2;
        void** sqes_ptr_out = (void**)a3;
        setup_params->flags &= ~(IORING_SETUP_CQE32 | IORING_SETUP_SQE128);
        uint32_t fd_io_uring = syscall(__NR_io_uring_setup, entries,
setup_params);
        uint32_t sq_ring_sz = setup_params->sq_off.array +
setup_params->sq_entries * sizeof(uint32_t);
        uint32_t cq_ring_sz = setup_params->cq_off.cqes +
setup_params->cq_entries * SIZEOF_IO_URING_CQE;
        uint32_t ring_sz = sq_ring_sz > cq_ring_sz ? sq_ring_sz : cq_ring_sz;
        *ring_ptr_out = mmap(0, ring_sz, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, fd_io_uring, IORING_OFF_SQ_RING);
        uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE;
        *sqes_ptr_out = mmap(0, sqes_sz, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, fd_io_uring, IORING_OFF_SQES);
        uint32_t* array = (uint32_t*)((uintptr_t)*ring_ptr_out +
setup_params->sq_off.array);
        for (uint32_t index = 0; index < entries; index++)
                array[index] = index;
        return fd_io_uring;
}

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/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)) {
        }
        if (symlink("/dev/binderfs", "./binderfs")) {
        }
}

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");
        sandbox_common_mount_tmpfs();
        loop();
        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");
}

static void execute_one(void);

#define WAIT_FLAGS __WALL

static void loop(void)
{
        int iter = 0;
        for (;; iter++) {
                int pid = fork();
                if (pid < 0)
        exit(1);
                if (pid == 0) {
                        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;
                }
        }
}

void execute_one(void)
{
                if (write(1, "executing program\n", sizeof("executing
program\n") - 1)) {}
        syscall(__NR_ioperm, /*from=*/0ul, /*num=*/0xd8ul, /*on=*/0x80000000ul);
        NONFAILING(*(uint64_t*)0x20000040 = 0);
        NONFAILING(*(uint64_t*)0x20000048 = 0);
        NONFAILING(memset((void*)0x20000050, 0, 24));
        NONFAILING(*(uint64_t*)0x20000068 = 0);
        NONFAILING(*(uint64_t*)0x20000070 = 0x20000000);
        syscall(__NR_ioctl, /*fd=*/-1, /*cmd=*/0xc0389424,
/*arg=*/0x20000040ul);
        NONFAILING(*(uint16_t*)0x20000040 = 0);
        NONFAILING(*(uint64_t*)0x20000048 = 0x20000000);
        syscall(__NR_setsockopt, /*fd=*/-1, /*level=*/1,
/*optname=*/0x1a, /*optval=*/0x20000040ul, /*optlen=*/0xfffffed3ul);
        NONFAILING(*(uint32_t*)0x20000004 = 0);
        NONFAILING(*(uint32_t*)0x20000008 = 0x4016);
        NONFAILING(*(uint32_t*)0x2000000c = 0);
        NONFAILING(*(uint32_t*)0x20000010 = 0);
        NONFAILING(*(uint32_t*)0x20000018 = -1);
        NONFAILING(memset((void*)0x2000001c, 0, 12));
        NONFAILING(syz_io_uring_setup(/*entries=*/0x29bc,
/*params=*/0x20000000, /*ring_ptr=*/0, /*sqes_ptr=*/0));
        NONFAILING(memcpy((void*)0x20000000, "9p\000", 3));
        syscall(__NR_mq_open, /*name=*/0x20000000ul,
/*flags=O_CREAT*/0x40ul, /*mode=*/0ul, /*attr=*/0ul);
        syscall(__NR_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);

}
int main(void)
{
                syscall(__NR_mmap, /*addr=*/0x1ffff000ul,
/*len=*/0x1000ul, /*prot=*/0ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/-1,
/*offset=*/0ul);
        syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
/*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/-1,
/*offset=*/0ul);
        syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul,
/*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul,
/*fd=*/-1, /*offset=*/0ul);
        const char* reason;
        (void)reason;
        install_segv_handler();
        for (procid = 0; procid < 2; procid++) {
                if (fork() == 0) {
                        do_sandbox_none();
                }
        }
        sleep(1000000);
        return 0;
}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ