Advertisement
qaqaq

Untitled

Aug 31st, 2022
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.00 KB | None | 0 0
  1.  
  2. #define _GNU_SOURCE
  3.  
  4. #include <dirent.h>
  5. #include <endian.h>
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <signal.h>
  9. #include <stdarg.h>
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/prctl.h>
  16. #include <sys/stat.h>
  17. #include <sys/syscall.h>
  18. #include <sys/types.h>
  19. #include <sys/wait.h>
  20. #include <time.h>
  21. #include <unistd.h>
  22. #include <usbg/function/hid.h>
  23. #include <usbg/function/loopback.h>
  24. #include <usbg/function/midi.h>
  25. #include <usbg/function/ms.h>
  26. #include <usbg/function/net.h>
  27. #include <usbg/function/printer.h>
  28. #include <usbg/usbg.h>
  29.  
  30. #include <linux/usb/ch9.h>
  31.  
  32. static unsigned long long procid;
  33.  
  34. static void sleep_ms(uint64_t ms)
  35. {
  36. usleep(ms * 1000);
  37. }
  38.  
  39. static uint64_t current_time_ms(void)
  40. {
  41. struct timespec ts;
  42. if (clock_gettime(CLOCK_MONOTONIC, &ts))
  43. exit(1);
  44. return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
  45. }
  46.  
  47. static bool write_file(const char* file, const char* what, ...)
  48. {
  49. char buf[1024];
  50. va_list args;
  51. va_start(args, what);
  52. vsnprintf(buf, sizeof(buf), what, args);
  53. va_end(args);
  54. buf[sizeof(buf) - 1] = 0;
  55. int len = strlen(buf);
  56. int fd = open(file, O_WRONLY | O_CLOEXEC);
  57. if (fd == -1)
  58. return false;
  59. if (write(fd, buf, len) != len) {
  60. int err = errno;
  61. close(fd);
  62. errno = err;
  63. return false;
  64. }
  65. close(fd);
  66. return true;
  67. }
  68.  
  69. #define MAX_FUNC_NUM 2
  70. #define MAX_DEVICE_NUM 8
  71. union usbg_function_attr {
  72. int default_attr;
  73. struct usbg_f_midi_attrs midi_attr;
  74. struct usbg_f_ms_attrs ms_attr;
  75. struct usbg_f_net_attrs net_attr;
  76. struct usbg_f_printer_attrs printer_attr;
  77. struct usbg_f_loopback_attrs loopback_attr;
  78. struct usbg_f_hid_attrs hid_attr;
  79. };
  80. struct usbg_func_config {
  81. usbg_function_type f_type;
  82. union usbg_function_attr f_attrs;
  83. };
  84.  
  85. struct usb_gadget_device {
  86. struct usbg_gadget_attrs* g_attrs;
  87. struct usbg_config_attrs* c_attrs;
  88. int func_num;
  89. struct usbg_func_config func_conf[MAX_FUNC_NUM];
  90. };
  91.  
  92. struct usb_gadget_device usb_device[MAX_DEVICE_NUM];
  93. struct usbg_gadget_strs g_strs = {.manufacturer = (char*)"Foo Inc.",
  94. .product = (char*)"Bar Gadget",
  95. .serial = (char*)"12345678"};
  96.  
  97. struct usbg_config_strs c_strs = {.configuration = (char*)"1xMIDI"};
  98.  
  99. static int remove_gadget(usbg_gadget* g)
  100. {
  101. int usbg_ret;
  102. usbg_udc* u;
  103. /* Check if gadget is enabled */
  104. u = usbg_get_gadget_udc(g);
  105. /* If gadget is enable we have to disable it first */
  106. if (u) {
  107. usbg_ret = usbg_disable_gadget(g);
  108. if (usbg_ret != USBG_SUCCESS) {
  109. fprintf(stderr, "Error on disable gadget udc\n");
  110. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  111. usbg_strerror((usbg_error)usbg_ret));
  112. goto out;
  113. }
  114. }
  115. /* Remove gadget with USBG_RM_RECURSE flag to remove
  116. * also its configurations, functions and strings */
  117. usbg_ret = usbg_rm_gadget(g, USBG_RM_RECURSE);
  118. if (usbg_ret != USBG_SUCCESS) {
  119. fprintf(stderr, "Error on gadget remove\n");
  120. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  121. usbg_strerror((usbg_error)usbg_ret));
  122. }
  123.  
  124. out:
  125. return usbg_ret;
  126. }
  127. static volatile long syz_detach_gadget_impl(int uid)
  128. {
  129. int usbg_ret;
  130. int ret = -1;
  131. usbg_state* s;
  132. usbg_gadget* g;
  133. const char* g_name;
  134. char g_name_target[10];
  135. sprintf(g_name_target, "g%d", uid);
  136. usbg_ret = usbg_init("/sys/kernel/config", &s);
  137. if (usbg_ret != USBG_SUCCESS) {
  138. fprintf(stderr, "Error on USB state init\n");
  139. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  140. usbg_strerror((usbg_error)usbg_ret));
  141. goto out1;
  142. }
  143. g = usbg_get_first_gadget(s);
  144. while (g != NULL) {
  145. /* Get current gadget attrs to be compared */
  146. g_name = usbg_get_gadget_name(g);
  147. /* Compare name with given values and remove if suitable */
  148. if (strcmp(g_name, g_name_target) == 0) {
  149. usbg_gadget* g_next = usbg_get_next_gadget(g);
  150. usbg_ret = remove_gadget(g);
  151. if (usbg_ret != USBG_SUCCESS)
  152. goto out2;
  153. g = g_next;
  154. } else {
  155. g = usbg_get_next_gadget(g);
  156. }
  157. }
  158. usleep(500000);
  159. ret = 0;
  160.  
  161. out2:
  162. usbg_cleanup(s);
  163. out1:
  164. return ret;
  165. }
  166.  
  167. static volatile long syz_attach_gadget_impl(struct usb_gadget_device* dev,
  168. int uid)
  169. {
  170. syz_detach_gadget_impl(uid);
  171. usbg_state* s;
  172. usbg_gadget* g;
  173. usbg_config* c;
  174. usbg_function* f[MAX_FUNC_NUM];
  175. usbg_udc* u;
  176. int ret = -1;
  177. int usbg_ret;
  178. char g_name[10];
  179. sprintf(g_name, "g%d", uid);
  180. usbg_ret = usbg_init("/sys/kernel/config", &s);
  181. if (usbg_ret != USBG_SUCCESS) {
  182. fprintf(stderr, "Error on usbg init\n");
  183. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  184. usbg_strerror((usbg_error)usbg_ret));
  185. goto out1;
  186. }
  187. usbg_ret = usbg_create_gadget(s, g_name, dev->g_attrs, &g_strs, &g);
  188. if (usbg_ret != USBG_SUCCESS) {
  189. fprintf(stderr, "Error on creating gadget\n");
  190. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  191. usbg_strerror((usbg_error)usbg_ret));
  192. goto out2;
  193. }
  194. for (int i = 0; i < dev->func_num; i++) {
  195. char f_name[10];
  196. sprintf(f_name, "func%d", i);
  197. if (dev->func_conf[i].f_attrs.default_attr == 0xffff)
  198. usbg_ret = usbg_create_function(g, dev->func_conf[i].f_type,
  199. (char*)f_name, NULL, &f[i]);
  200. else
  201. usbg_ret =
  202. usbg_create_function(g, dev->func_conf[i].f_type, (char*)f_name,
  203. &(dev->func_conf[i].f_attrs), &f[i]);
  204. if (usbg_ret != USBG_SUCCESS) {
  205. fprintf(stderr, "Error on creating gadget func\n");
  206. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  207. usbg_strerror((usbg_error)usbg_ret));
  208. goto out2;
  209. }
  210. }
  211. usbg_ret = usbg_create_config(g, 1, "The only one config", dev->c_attrs,
  212. &c_strs, &c);
  213. if (usbg_ret != USBG_SUCCESS) {
  214. fprintf(stderr, "Error on creating gadget config\n");
  215. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  216. usbg_strerror((usbg_error)usbg_ret));
  217. goto out2;
  218. }
  219. for (int i = 0; i < dev->func_num; i++) {
  220. char f_name[10];
  221. sprintf(f_name, "f_name.%d", i);
  222. usbg_ret = usbg_add_config_function(c, (char*)f_name, f[i]);
  223. if (usbg_ret != USBG_SUCCESS) {
  224. fprintf(stderr, "Error on adding func to config\n");
  225. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  226. usbg_strerror((usbg_error)usbg_ret));
  227. goto out2;
  228. }
  229. }
  230. u = usbg_get_first_udc(s);
  231. if (uid > 0) {
  232. for (int i = 0; i < uid; i++) {
  233. u = usbg_get_next_udc(u);
  234. }
  235. }
  236. usbg_ret = usbg_enable_gadget(g, u);
  237. if (usbg_ret != USBG_SUCCESS) {
  238. fprintf(stderr, "Error on enabling udc\n");
  239. fprintf(stderr, "Error: %s : %s\n", usbg_error_name((usbg_error)usbg_ret),
  240. usbg_strerror((usbg_error)usbg_ret));
  241. goto out2;
  242. }
  243. ret = 0;
  244.  
  245. out2:
  246. usbg_cleanup(s);
  247.  
  248. out1:
  249. return ret;
  250. }
  251.  
  252. static void parse_dev_descriptors(const char* buffer,
  253. struct usb_gadget_device* dev)
  254. {
  255. printf("begin to parse...\n");
  256. memset(dev, 0, sizeof(*dev));
  257. dev->g_attrs = (struct usbg_gadget_attrs*)buffer;
  258. dev->c_attrs =
  259. (struct usbg_config_attrs*)(buffer + sizeof(struct usbg_gadget_attrs));
  260. dev->func_num = *(int*)(buffer + sizeof(struct usbg_gadget_attrs) +
  261. sizeof(struct usbg_config_attrs) + sizeof(int16_t));
  262. int start_attr = sizeof(struct usbg_gadget_attrs) +
  263. sizeof(struct usbg_config_attrs) + sizeof(int16_t) +
  264. 2 * sizeof(int32_t);
  265. int conf_size = 40;
  266. for (int i = 0; i < dev->func_num; i++) {
  267. dev->func_conf[i] =
  268. *(struct usbg_func_config*)(buffer + start_attr + i * conf_size);
  269. if (dev->func_conf[i].f_type == USBG_F_HID) {
  270. struct usbg_f_hid_attrs* hid_attr = &(dev->func_conf[i].f_attrs.hid_attr);
  271. struct usbg_f_hid_report_desc* report_desc = &(hid_attr->report_desc);
  272. report_desc->len = strlen(report_desc->desc);
  273. conf_size = 48;
  274. }
  275. }
  276. }
  277.  
  278. static volatile long syz_attach_gadget(volatile long a0, volatile long a1)
  279. {
  280. const char* dev = (const char*)a0;
  281. uint64_t uid = a1;
  282. parse_dev_descriptors(dev, &usb_device[uid]);
  283. return syz_attach_gadget_impl(&usb_device[uid], uid);
  284. }
  285.  
  286. static void kill_and_wait(int pid, int* status)
  287. {
  288. kill(-pid, SIGKILL);
  289. kill(pid, SIGKILL);
  290. for (int i = 0; i < 100; i++) {
  291. if (waitpid(-1, status, WNOHANG | __WALL) == pid)
  292. return;
  293. usleep(1000);
  294. }
  295. DIR* dir = opendir("/sys/fs/fuse/connections");
  296. if (dir) {
  297. for (;;) {
  298. struct dirent* ent = readdir(dir);
  299. if (!ent)
  300. break;
  301. if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
  302. continue;
  303. char abort[300];
  304. snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
  305. ent->d_name);
  306. int fd = open(abort, O_WRONLY);
  307. if (fd == -1) {
  308. continue;
  309. }
  310. if (write(fd, abort, 1) < 0) {
  311. }
  312. close(fd);
  313. }
  314. closedir(dir);
  315. } else {
  316. }
  317. while (waitpid(-1, status, __WALL) != pid) {
  318. }
  319. }
  320.  
  321. static void setup_test()
  322. {
  323. prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
  324. setpgrp();
  325. write_file("/proc/self/oom_score_adj", "1000");
  326. }
  327.  
  328. static void execute_one(void);
  329.  
  330. #define WAIT_FLAGS __WALL
  331.  
  332. static void loop(void)
  333. {
  334. int iter = 0;
  335. for (;; iter++) {
  336. int pid = fork();
  337. if (pid < 0)
  338. exit(1);
  339. if (pid == 0) {
  340. setup_test();
  341. execute_one();
  342. exit(0);
  343. }
  344. int status = 0;
  345. uint64_t start = current_time_ms();
  346. for (;;) {
  347. if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
  348. break;
  349. sleep_ms(1);
  350. if (current_time_ms() - start < 5000)
  351. continue;
  352. kill_and_wait(pid, &status);
  353. break;
  354. }
  355. }
  356. }
  357.  
  358. void execute_one(void)
  359. {
  360. *(uint16_t*)0x20000000 = 0x310;
  361. *(uint8_t*)0x20000002 = 0;
  362. *(uint8_t*)0x20000003 = 0;
  363. *(uint8_t*)0x20000004 = 0;
  364. *(uint8_t*)0x20000005 = 0x70;
  365. *(uint16_t*)0x20000006 = 0x6a3;
  366. *(uint16_t*)0x20000008 = 0xff04;
  367. *(uint16_t*)0x2000000a = 0;
  368. *(uint8_t*)0x2000000c = 0xe0;
  369. *(uint8_t*)0x2000000d = 0x5c;
  370. *(uint32_t*)0x20000010 = 2;
  371. *(uint8_t*)0x20000018 = 0xa;
  372. *(uint32_t*)0x20000020 = 0xffff;
  373. *(uint8_t*)0x20000040 = 7;
  374. *(uint32_t*)0x20000048 = 0xffff;
  375. syz_attach_gadget(0x20000000, 1);
  376. }
  377. int main(void)
  378. {
  379. syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  380. syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  381. syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  382. for (procid = 0; procid < 8; procid++) {
  383. if (fork() == 0) {
  384. loop();
  385. }
  386. }
  387. sleep(1000000);
  388. return 0;
  389. }
  390.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement