Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <dirent.h>
- #include <endian.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/prctl.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <time.h>
- #include <unistd.h>
- #include <usbg/function/hid.h>
- #include <usbg/function/loopback.h>
- #include <usbg/function/midi.h>
- #include <usbg/function/ms.h>
- #include <usbg/function/net.h>
- #include <usbg/function/printer.h>
- #include <usbg/usbg.h>
- #include <linux/usb/ch9.h>
- 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 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 MAX_FUNC_NUM 2
- #define MAX_DEVICE_NUM 8
- union usbg_function_attr {
- int default_attr;
- struct usbg_f_midi_attrs midi_attr;
- struct usbg_f_ms_attrs ms_attr;
- struct usbg_f_net_attrs net_attr;
- struct usbg_f_printer_attrs printer_attr;
- struct usbg_f_loopback_attrs loopback_attr;
- struct usbg_f_hid_attrs hid_attr;
- };
- struct usbg_func_config {
- usbg_function_type f_type;
- union usbg_function_attr f_attrs;
- };
- struct usb_gadget_device {
- struct usbg_gadget_attrs* g_attrs;
- struct usbg_config_attrs* c_attrs;
- int func_num;
- struct usbg_func_config func_conf[MAX_FUNC_NUM];
- };
- struct usb_gadget_device usb_device[MAX_DEVICE_NUM];
- struct usbg_gadget_strs g_strs = {.manufacturer = (char*)"Foo Inc.",
- .product = (char*)"Bar Gadget",
- .serial = (char*)"12345678"};
- struct usbg_config_strs c_strs = {.configuration = (char*)"1xMIDI"};
- static int remove_gadget(usbg_gadget* g)
- {
- int usbg_ret;
- usbg_udc* u;
- /* Check if gadget is enabled */
- u = usbg_get_gadget_udc(g);
- /* If gadget is enable we have to disable it first */
- if (u) {
- usbg_ret = usbg_disable_gadget(g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on disable gadget udc\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out;
- }
- }
- /* Remove gadget with USBG_RM_RECURSE flag to remove
- * also its configurations, functions and strings */
- usbg_ret = usbg_rm_gadget(g, USBG_RM_RECURSE);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on gadget remove\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- }
- out:
- return usbg_ret;
- }
- static volatile long syz_detach_gadget_impl(int uid)
- {
- int usbg_ret;
- int ret = -1;
- usbg_state* s;
- usbg_gadget* g;
- const char* g_name;
- char g_name_target[10];
- sprintf(g_name_target, "g%d", uid);
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB state init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out1;
- }
- g = usbg_get_first_gadget(s);
- while (g != NULL) {
- /* Get current gadget attrs to be compared */
- g_name = usbg_get_gadget_name(g);
- /* Compare name with given values and remove if suitable */
- if (strcmp(g_name, g_name_target) == 0) {
- usbg_gadget* g_next = usbg_get_next_gadget(g);
- usbg_ret = remove_gadget(g);
- if (usbg_ret != USBG_SUCCESS)
- goto out2;
- g = g_next;
- } else {
- g = usbg_get_next_gadget(g);
- }
- }
- usleep(500000);
- ret = 0;
- out2:
- usbg_cleanup(s);
- out1:
- return ret;
- }
- static volatile long syz_attach_gadget_impl(struct usb_gadget_device* dev,
- int uid)
- {
- syz_detach_gadget_impl(uid);
- usbg_state* s;
- usbg_gadget* g;
- usbg_config* c;
- usbg_function* f[MAX_FUNC_NUM];
- usbg_udc* u;
- int ret = -1;
- int usbg_ret;
- char g_name[10];
- sprintf(g_name, "g%d", uid);
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on usbg init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out1;
- }
- usbg_ret = usbg_create_gadget(s, g_name, dev->g_attrs, &g_strs, &g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on creating gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out2;
- }
- for (int i = 0; i < dev->func_num; i++) {
- char f_name[10];
- sprintf(f_name, "func%d", i);
- if (dev->func_conf[i].f_attrs.default_attr == 0xffff)
- usbg_ret = usbg_create_function(g, dev->func_conf[i].f_type,
- (char*)f_name, NULL, &f[i]);
- else
- usbg_ret =
- usbg_create_function(g, dev->func_conf[i].f_type, (char*)f_name,
- &(dev->func_conf[i].f_attrs), &f[i]);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on creating gadget func\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out2;
- }
- }
- usbg_ret = usbg_create_config(g, 1, "The only one config", dev->c_attrs,
- &c_strs, &c);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on creating gadget config\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out2;
- }
- for (int i = 0; i < dev->func_num; i++) {
- char f_name[10];
- sprintf(f_name, "f_name.%d", i);
- usbg_ret = usbg_add_config_function(c, (char*)f_name, f[i]);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on adding func to config\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out2;
- }
- }
- u = usbg_get_first_udc(s);
- if (uid > 0) {
- for (int i = 0; i < uid; i++) {
- u = usbg_get_next_udc(u);
- }
- }
- usbg_ret = usbg_enable_gadget(g, u);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on enabling udc\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
- usbg_strerror((usbg_error)usbg_ret));
- goto out2;
- }
- ret = 0;
- out2:
- usbg_cleanup(s);
- out1:
- return ret;
- }
- static void parse_dev_descriptors(const char* buffer,
- struct usb_gadget_device* dev)
- {
- printf("begin to parse...\n");
- memset(dev, 0, sizeof(*dev));
- dev->g_attrs = (struct usbg_gadget_attrs*)buffer;
- dev->c_attrs =
- (struct usbg_config_attrs*)(buffer + sizeof(struct usbg_gadget_attrs));
- dev->func_num = *(int*)(buffer + sizeof(struct usbg_gadget_attrs) +
- sizeof(struct usbg_config_attrs) + sizeof(int16_t));
- int start_attr = sizeof(struct usbg_gadget_attrs) +
- sizeof(struct usbg_config_attrs) + sizeof(int16_t) +
- 2 * sizeof(int32_t);
- int conf_size = 40;
- for (int i = 0; i < dev->func_num; i++) {
- dev->func_conf[i] =
- *(struct usbg_func_config*)(buffer + start_attr + i * conf_size);
- if (dev->func_conf[i].f_type == USBG_F_HID) {
- struct usbg_f_hid_attrs* hid_attr = &(dev->func_conf[i].f_attrs.hid_attr);
- struct usbg_f_hid_report_desc* report_desc = &(hid_attr->report_desc);
- report_desc->len = strlen(report_desc->desc);
- conf_size = 48;
- }
- }
- }
- static volatile long syz_attach_gadget(volatile long a0, volatile long a1)
- {
- const char* dev = (const char*)a0;
- uint64_t uid = a1;
- parse_dev_descriptors(dev, &usb_device[uid]);
- return syz_attach_gadget_impl(&usb_device[uid], uid);
- }
- 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 (;;) {
- if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
- break;
- sleep_ms(1);
- if (current_time_ms() - start < 5000)
- continue;
- kill_and_wait(pid, &status);
- break;
- }
- }
- }
- void execute_one(void)
- {
- *(uint16_t*)0x20000000 = 0x310;
- *(uint8_t*)0x20000002 = 0;
- *(uint8_t*)0x20000003 = 0;
- *(uint8_t*)0x20000004 = 0;
- *(uint8_t*)0x20000005 = 0x70;
- *(uint16_t*)0x20000006 = 0x6a3;
- *(uint16_t*)0x20000008 = 0xff04;
- *(uint16_t*)0x2000000a = 0;
- *(uint8_t*)0x2000000c = 0xe0;
- *(uint8_t*)0x2000000d = 0x5c;
- *(uint32_t*)0x20000010 = 2;
- *(uint8_t*)0x20000018 = 0xa;
- *(uint32_t*)0x20000020 = 0xffff;
- *(uint8_t*)0x20000040 = 7;
- *(uint32_t*)0x20000048 = 0xffff;
- syz_attach_gadget(0x20000000, 1);
- }
- int main(void)
- {
- syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
- syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
- syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
- for (procid = 0; procid < 8; procid++) {
- if (fork() == 0) {
- loop();
- }
- }
- sleep(1000000);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement