map[SimplifiedCRepro:// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/usb/ch9.h>
static unsigned long long procid;
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 VHCI_HC_PORTS 8
#define VHCI_PORTS (VHCI_HC_PORTS * 2)
static long syz_usbip_server_init(volatile long a0)
{
static int port_alloc[2];
int speed = (int)a0;
bool usb3 = (speed == USB_SPEED_SUPER);
int socket_pair[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) {
return -1;
}
int client_fd = socket_pair[0];
int server_fd = socket_pair[1];
int available_port_num = __atomic_fetch_add(&port_alloc[usb3], 1, __ATOMIC_RELAXED);
if (available_port_num > VHCI_HC_PORTS) {
return -1;
}
int port_num = procid * VHCI_PORTS + usb3 * VHCI_HC_PORTS + available_port_num;
char buffer[100];
sprintf(buffer, "%d %d %s %d", port_num, client_fd, "0", speed);
write_file("/sys/devices/platform/vhci_hcd.0/attach", buffer);
return server_fd;
}
#define USLEEP_FORKED_CHILD (3 * 50 *1000)
static long handle_clone_ret(long ret)
{
if (ret != 0) {
return ret;
}
usleep(USLEEP_FORKED_CHILD);
syscall(__NR_exit, 0);
while (1) {
}
}
static long syz_clone(volatile long flags, volatile long stack, volatile long stack_len,
volatile long ptid, volatile long ctid, volatile long tls)
{
long sp = (stack + stack_len) & ~15;
long ret = (long)syscall(__NR_clone, flags & ~CLONE_VM, sp, ptid, ctid, tls);
return handle_clone_ret(ret);
}
uint64_t r[1] = {0x0};
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;
intptr_t res = 0;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
// syz_usbip_server_init arguments: [
// speed: usbip_device_speed = 0x5 (8 bytes)
// ]
// returns fd_usbip_server
syz_usbip_server_init(/*speed=USB_SPEED_SUPER*/5);
// syz_clone arguments: [
// flags: clone_flags = 0x0 (8 bytes)
// stack: nil
// stack_len: bytesize = 0x0 (8 bytes)
// parentid: nil
// childtid: nil
// tls: nil
// ]
// returns pid
res = -1;
res = syz_clone(/*flags=*/0, /*stack=*/0, /*stack_len=*/0, /*parentid=*/0, /*childtid=*/0, /*tls=*/0);
if (res != -1)
r[0] = res;
// ptrace arguments: [
// req: ptrace_req = 0x10 (8 bytes)
// pid: pid (resource)
// ]
syscall(__NR_ptrace, /*req=PTRACE_ATTACH*/0x10ul, /*pid=*/r[0], 0, 0);
return 0;
}
]