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 <linux/usb/ch9.h>
- #include <string.h>
- #include <time.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>
- #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_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*)"1xconf"};
- static volatile long syz_attach_gadget_impl(struct usb_gadget_device* dev, int 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 int remove_gadget(usbg_gadget* g)
- {
- int usbg_ret;
- usbg_udc* u;
- u = usbg_get_gadget_udc(g);
- 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;
- }
- }
- 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) {
- g_name = usbg_get_gadget_name(g);
- 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 void parse_dev_descriptors(const char* buffer, struct usb_gadget_device* dev)
- {
- 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;
- printf("conf_size: %x\n", conf_size);
- for (int i = 0; i < dev->func_num; i++) {
- dev->func_conf[i] = *(struct usbg_func_config*)(buffer + start_attr + i * conf_size);
- }
- }
- 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 volatile long syz_detach_gadget(volatile long a0)
- {
- int uid = a0;
- return syz_detach_gadget_impl(uid);
- }
- #include <endian.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/syscall.h>
- #include <sys/types.h>
- #include <unistd.h>
- 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);
- syz_detach_gadget(5);
- *(uint16_t*)0x20000000 = 0x320;
- *(uint8_t*)0x20000002 = 0;
- *(uint8_t*)0x20000003 = 0;
- *(uint8_t*)0x20000004 = 0;
- *(uint8_t*)0x20000005 = 0x50;
- *(uint16_t*)0x20000006 = 0x45e;
- *(uint16_t*)0x20000008 = 0x6d;
- *(uint16_t*)0x2000000a = 0;
- *(uint8_t*)0x2000000c = 0xc0;
- *(uint8_t*)0x2000000d = 0xaa;
- *(uint32_t*)0x20000010 = 1;
- *(uint8_t*)0x20000018 = 0xc;
- *(uint32_t*)0x20000020 = 0xffff;
- syz_attach_gadget(0x20000000, 5);
- return 0;
- }
Add Comment
Please, Sign In to add comment