zzqq0103

Untitled

Mar 17th, 2024
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.30 KB | None | 0 0
  1. #define _GNU_SOURCE
  2.  
  3. #include <dirent.h>
  4. #include <endian.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <pthread.h>
  8. #include <setjmp.h>
  9. #include <signal.h>
  10. #include <stdarg.h>
  11. #include <stdbool.h>
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/ioctl.h>
  18. #include <sys/mman.h>
  19. #include <sys/mount.h>
  20. #include <sys/prctl.h>
  21. #include <sys/stat.h>
  22. #include <sys/syscall.h>
  23. #include <sys/types.h>
  24. #include <sys/wait.h>
  25. #include <time.h>
  26. #include <unistd.h>
  27.  
  28. #include <linux/futex.h>
  29. #include <linux/loop.h>
  30.  
  31. #ifndef __NR_memfd_create
  32. #define __NR_memfd_create 319
  33. #endif
  34.  
  35. static unsigned long long procid;
  36.  
  37. static void sleep_ms(uint64_t ms)
  38. {
  39. usleep(ms * 1000);
  40. }
  41.  
  42. static uint64_t current_time_ms(void)
  43. {
  44. struct timespec ts;
  45. if (clock_gettime(CLOCK_MONOTONIC, &ts))
  46. exit(1);
  47. return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
  48. }
  49.  
  50. static void use_temporary_dir(void)
  51. {
  52. char tmpdir_template[] = "./syzkaller.XXXXXX";
  53. char* tmpdir = mkdtemp(tmpdir_template);
  54. if (!tmpdir)
  55. exit(1);
  56. if (chmod(tmpdir, 0777))
  57. exit(1);
  58. if (chdir(tmpdir))
  59. exit(1);
  60. }
  61.  
  62. static void thread_start(void* (*fn)(void*), void* arg)
  63. {
  64. pthread_t th;
  65. pthread_attr_t attr;
  66. pthread_attr_init(&attr);
  67. pthread_attr_setstacksize(&attr, 128 << 10);
  68. int i = 0;
  69. for (; i < 100; i++) {
  70. if (pthread_create(&th, &attr, fn, arg) == 0) {
  71. pthread_attr_destroy(&attr);
  72. return;
  73. }
  74. if (errno == EAGAIN) {
  75. usleep(50);
  76. continue;
  77. }
  78. break;
  79. }
  80. exit(1);
  81. }
  82.  
  83. typedef struct {
  84. int state;
  85. } event_t;
  86.  
  87. static void event_init(event_t* ev)
  88. {
  89. ev->state = 0;
  90. }
  91.  
  92. static void event_reset(event_t* ev)
  93. {
  94. ev->state = 0;
  95. }
  96.  
  97. static void event_set(event_t* ev)
  98. {
  99. if (ev->state)
  100. exit(1);
  101. __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
  102. syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
  103. }
  104.  
  105. static void event_wait(event_t* ev)
  106. {
  107. while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
  108. syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
  109. }
  110.  
  111. static int event_isset(event_t* ev)
  112. {
  113. return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
  114. }
  115.  
  116. static int event_timedwait(event_t* ev, uint64_t timeout)
  117. {
  118. uint64_t start = current_time_ms();
  119. uint64_t now = start;
  120. for (;;) {
  121. uint64_t remain = timeout - (now - start);
  122. struct timespec ts;
  123. ts.tv_sec = remain / 1000;
  124. ts.tv_nsec = (remain % 1000) * 1000 * 1000;
  125. syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
  126. if (__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
  127. return 1;
  128. now = current_time_ms();
  129. if (now - start > timeout)
  130. return 0;
  131. }
  132. }
  133.  
  134. static bool write_file(const char* file, const char* what, ...)
  135. {
  136. char buf[1024];
  137. va_list args;
  138. va_start(args, what);
  139. vsnprintf(buf, sizeof(buf), what, args);
  140. va_end(args);
  141. buf[sizeof(buf) - 1] = 0;
  142. int len = strlen(buf);
  143. int fd = open(file, O_WRONLY | O_CLOEXEC);
  144. if (fd == -1)
  145. return false;
  146. if (write(fd, buf, len) != len) {
  147. int err = errno;
  148. close(fd);
  149. errno = err;
  150. return false;
  151. }
  152. close(fd);
  153. return true;
  154. }
  155.  
  156. //% This code is derived from puff.{c,h}, found in the zlib development. The
  157. //% original files come with the following copyright notice:
  158.  
  159. //% Copyright (C) 2002-2013 Mark Adler, all rights reserved
  160. //% version 2.3, 21 Jan 2013
  161. //% This software is provided 'as-is', without any express or implied
  162. //% warranty. In no event will the author be held liable for any damages
  163. //% arising from the use of this software.
  164. //% Permission is granted to anyone to use this software for any purpose,
  165. //% including commercial applications, and to alter it and redistribute it
  166. //% freely, subject to the following restrictions:
  167. //% 1. The origin of this software must not be misrepresented; you must not
  168. //% claim that you wrote the original software. If you use this software
  169. //% in a product, an acknowledgment in the product documentation would be
  170. //% appreciated but is not required.
  171. //% 2. Altered source versions must be plainly marked as such, and must not be
  172. //% misrepresented as being the original software.
  173. //% 3. This notice may not be removed or altered from any source distribution.
  174. //% Mark Adler [email protected]
  175.  
  176. //% BEGIN CODE DERIVED FROM puff.{c,h}
  177.  
  178. #define MAXBITS 15
  179. #define MAXLCODES 286
  180. #define MAXDCODES 30
  181. #define MAXCODES (MAXLCODES + MAXDCODES)
  182. #define FIXLCODES 288
  183.  
  184. struct puff_state {
  185. unsigned char* out;
  186. unsigned long outlen;
  187. unsigned long outcnt;
  188. const unsigned char* in;
  189. unsigned long inlen;
  190. unsigned long incnt;
  191. int bitbuf;
  192. int bitcnt;
  193. jmp_buf env;
  194. };
  195. static int puff_bits(struct puff_state* s, int need)
  196. {
  197. long val = s->bitbuf;
  198. while (s->bitcnt < need) {
  199. if (s->incnt == s->inlen)
  200. longjmp(s->env, 1);
  201. val |= (long)(s->in[s->incnt++]) << s->bitcnt;
  202. s->bitcnt += 8;
  203. }
  204. s->bitbuf = (int)(val >> need);
  205. s->bitcnt -= need;
  206. return (int)(val & ((1L << need) - 1));
  207. }
  208. static int puff_stored(struct puff_state* s)
  209. {
  210. s->bitbuf = 0;
  211. s->bitcnt = 0;
  212. if (s->incnt + 4 > s->inlen)
  213. return 2;
  214. unsigned len = s->in[s->incnt++];
  215. len |= s->in[s->incnt++] << 8;
  216. if (s->in[s->incnt++] != (~len & 0xff) ||
  217. s->in[s->incnt++] != ((~len >> 8) & 0xff))
  218. return -2;
  219. if (s->incnt + len > s->inlen)
  220. return 2;
  221. if (s->outcnt + len > s->outlen)
  222. return 1;
  223. for (; len--; s->outcnt++, s->incnt++) {
  224. if (s->in[s->incnt])
  225. s->out[s->outcnt] = s->in[s->incnt];
  226. }
  227. return 0;
  228. }
  229. struct puff_huffman {
  230. short* count;
  231. short* symbol;
  232. };
  233. static int puff_decode(struct puff_state* s, const struct puff_huffman* h)
  234. {
  235. int first = 0;
  236. int index = 0;
  237. int bitbuf = s->bitbuf;
  238. int left = s->bitcnt;
  239. int code = first = index = 0;
  240. int len = 1;
  241. short* next = h->count + 1;
  242. while (1) {
  243. while (left--) {
  244. code |= bitbuf & 1;
  245. bitbuf >>= 1;
  246. int count = *next++;
  247. if (code - count < first) {
  248. s->bitbuf = bitbuf;
  249. s->bitcnt = (s->bitcnt - len) & 7;
  250. return h->symbol[index + (code - first)];
  251. }
  252. index += count;
  253. first += count;
  254. first <<= 1;
  255. code <<= 1;
  256. len++;
  257. }
  258. left = (MAXBITS + 1) - len;
  259. if (left == 0)
  260. break;
  261. if (s->incnt == s->inlen)
  262. longjmp(s->env, 1);
  263. bitbuf = s->in[s->incnt++];
  264. if (left > 8)
  265. left = 8;
  266. }
  267. return -10;
  268. }
  269. static int puff_construct(struct puff_huffman* h, const short* length, int n)
  270. {
  271. int len;
  272. for (len = 0; len <= MAXBITS; len++)
  273. h->count[len] = 0;
  274. int symbol;
  275. for (symbol = 0; symbol < n; symbol++)
  276. (h->count[length[symbol]])++;
  277. if (h->count[0] == n)
  278. return 0;
  279. int left = 1;
  280. for (len = 1; len <= MAXBITS; len++) {
  281. left <<= 1;
  282. left -= h->count[len];
  283. if (left < 0)
  284. return left;
  285. }
  286. short offs[MAXBITS + 1];
  287. offs[1] = 0;
  288. for (len = 1; len < MAXBITS; len++)
  289. offs[len + 1] = offs[len] + h->count[len];
  290. for (symbol = 0; symbol < n; symbol++)
  291. if (length[symbol] != 0)
  292. h->symbol[offs[length[symbol]]++] = symbol;
  293. return left;
  294. }
  295. static int puff_codes(struct puff_state* s, const struct puff_huffman* lencode,
  296. const struct puff_huffman* distcode)
  297. {
  298. static const short lens[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
  299. 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
  300. 67, 83, 99, 115, 131, 163, 195, 227, 258};
  301. static const short lext[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
  302. 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
  303. static const short dists[30] = {
  304. 1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
  305. 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
  306. 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
  307. static const short dext[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
  308. 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
  309. 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
  310. int symbol;
  311. do {
  312. symbol = puff_decode(s, lencode);
  313. if (symbol < 0)
  314. return symbol;
  315. if (symbol < 256) {
  316. if (s->outcnt == s->outlen)
  317. return 1;
  318. if (symbol)
  319. s->out[s->outcnt] = symbol;
  320. s->outcnt++;
  321. } else if (symbol > 256) {
  322. symbol -= 257;
  323. if (symbol >= 29)
  324. return -10;
  325. int len = lens[symbol] + puff_bits(s, lext[symbol]);
  326. symbol = puff_decode(s, distcode);
  327. if (symbol < 0)
  328. return symbol;
  329. unsigned dist = dists[symbol] + puff_bits(s, dext[symbol]);
  330. if (dist > s->outcnt)
  331. return -11;
  332. if (s->outcnt + len > s->outlen)
  333. return 1;
  334. while (len--) {
  335. if (dist <= s->outcnt && s->out[s->outcnt - dist])
  336. s->out[s->outcnt] = s->out[s->outcnt - dist];
  337. s->outcnt++;
  338. }
  339. }
  340. } while (symbol != 256);
  341. return 0;
  342. }
  343. static int puff_fixed(struct puff_state* s)
  344. {
  345. static int virgin = 1;
  346. static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
  347. static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
  348. static struct puff_huffman lencode, distcode;
  349. if (virgin) {
  350. lencode.count = lencnt;
  351. lencode.symbol = lensym;
  352. distcode.count = distcnt;
  353. distcode.symbol = distsym;
  354. short lengths[FIXLCODES];
  355. int symbol;
  356. for (symbol = 0; symbol < 144; symbol++)
  357. lengths[symbol] = 8;
  358. for (; symbol < 256; symbol++)
  359. lengths[symbol] = 9;
  360. for (; symbol < 280; symbol++)
  361. lengths[symbol] = 7;
  362. for (; symbol < FIXLCODES; symbol++)
  363. lengths[symbol] = 8;
  364. puff_construct(&lencode, lengths, FIXLCODES);
  365. for (symbol = 0; symbol < MAXDCODES; symbol++)
  366. lengths[symbol] = 5;
  367. puff_construct(&distcode, lengths, MAXDCODES);
  368. virgin = 0;
  369. }
  370. return puff_codes(s, &lencode, &distcode);
  371. }
  372. static int puff_dynamic(struct puff_state* s)
  373. {
  374. static const short order[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
  375. 11, 4, 12, 3, 13, 2, 14, 1, 15};
  376. int nlen = puff_bits(s, 5) + 257;
  377. int ndist = puff_bits(s, 5) + 1;
  378. int ncode = puff_bits(s, 4) + 4;
  379. if (nlen > MAXLCODES || ndist > MAXDCODES)
  380. return -3;
  381. short lengths[MAXCODES];
  382. int index;
  383. for (index = 0; index < ncode; index++)
  384. lengths[order[index]] = puff_bits(s, 3);
  385. for (; index < 19; index++)
  386. lengths[order[index]] = 0;
  387. short lencnt[MAXBITS + 1], lensym[MAXLCODES];
  388. struct puff_huffman lencode = {lencnt, lensym};
  389. int err = puff_construct(&lencode, lengths, 19);
  390. if (err != 0)
  391. return -4;
  392. index = 0;
  393. while (index < nlen + ndist) {
  394. int symbol;
  395. int len;
  396. symbol = puff_decode(s, &lencode);
  397. if (symbol < 0)
  398. return symbol;
  399. if (symbol < 16)
  400. lengths[index++] = symbol;
  401. else {
  402. len = 0;
  403. if (symbol == 16) {
  404. if (index == 0)
  405. return -5;
  406. len = lengths[index - 1];
  407. symbol = 3 + puff_bits(s, 2);
  408. } else if (symbol == 17)
  409. symbol = 3 + puff_bits(s, 3);
  410. else
  411. symbol = 11 + puff_bits(s, 7);
  412. if (index + symbol > nlen + ndist)
  413. return -6;
  414. while (symbol--)
  415. lengths[index++] = len;
  416. }
  417. }
  418. if (lengths[256] == 0)
  419. return -9;
  420. err = puff_construct(&lencode, lengths, nlen);
  421. if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
  422. return -7;
  423. short distcnt[MAXBITS + 1], distsym[MAXDCODES];
  424. struct puff_huffman distcode = {distcnt, distsym};
  425. err = puff_construct(&distcode, lengths + nlen, ndist);
  426. if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
  427. return -8;
  428. return puff_codes(s, &lencode, &distcode);
  429. }
  430. static int puff(unsigned char* dest, unsigned long* destlen,
  431. const unsigned char* source, unsigned long sourcelen)
  432. {
  433. struct puff_state s = {
  434. .out = dest,
  435. .outlen = *destlen,
  436. .outcnt = 0,
  437. .in = source,
  438. .inlen = sourcelen,
  439. .incnt = 0,
  440. .bitbuf = 0,
  441. .bitcnt = 0,
  442. };
  443. int err;
  444. if (setjmp(s.env) != 0)
  445. err = 2;
  446. else {
  447. int last;
  448. do {
  449. last = puff_bits(&s, 1);
  450. int type = puff_bits(&s, 2);
  451. err = type == 0 ? puff_stored(&s)
  452. : (type == 1 ? puff_fixed(&s)
  453. : (type == 2 ? puff_dynamic(&s) : -1));
  454. if (err != 0)
  455. break;
  456. } while (!last);
  457. }
  458. *destlen = s.outcnt;
  459. return err;
  460. }
  461.  
  462. //% END CODE DERIVED FROM puff.{c,h}
  463.  
  464. #define ZLIB_HEADER_WIDTH 2
  465.  
  466. static int puff_zlib_to_file(const unsigned char* source,
  467. unsigned long sourcelen, int dest_fd)
  468. {
  469. if (sourcelen < ZLIB_HEADER_WIDTH)
  470. return 0;
  471. source += ZLIB_HEADER_WIDTH;
  472. sourcelen -= ZLIB_HEADER_WIDTH;
  473. const unsigned long max_destlen = 132 << 20;
  474. void* ret = mmap(0, max_destlen, PROT_WRITE | PROT_READ,
  475. MAP_PRIVATE | MAP_ANON, -1, 0);
  476. if (ret == MAP_FAILED)
  477. return -1;
  478. unsigned char* dest = (unsigned char*)ret;
  479. unsigned long destlen = max_destlen;
  480. int err = puff(dest, &destlen, source, sourcelen);
  481. if (err) {
  482. munmap(dest, max_destlen);
  483. errno = -err;
  484. return -1;
  485. }
  486. if (write(dest_fd, dest, destlen) != (ssize_t)destlen) {
  487. munmap(dest, max_destlen);
  488. return -1;
  489. }
  490. return munmap(dest, max_destlen);
  491. }
  492.  
  493. static int setup_loop_device(unsigned char* data, unsigned long size,
  494. const char* loopname, int* loopfd_p)
  495. {
  496. int err = 0, loopfd = -1;
  497. int memfd = syscall(__NR_memfd_create, "syzkaller", 0);
  498. if (memfd == -1) {
  499. err = errno;
  500. goto error;
  501. }
  502. if (puff_zlib_to_file(data, size, memfd)) {
  503. err = errno;
  504. goto error_close_memfd;
  505. }
  506. loopfd = open(loopname, O_RDWR);
  507. if (loopfd == -1) {
  508. err = errno;
  509. goto error_close_memfd;
  510. }
  511. if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
  512. if (errno != EBUSY) {
  513. err = errno;
  514. goto error_close_loop;
  515. }
  516. ioctl(loopfd, LOOP_CLR_FD, 0);
  517. usleep(1000);
  518. if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
  519. err = errno;
  520. goto error_close_loop;
  521. }
  522. }
  523. close(memfd);
  524. *loopfd_p = loopfd;
  525. return 0;
  526.  
  527. error_close_loop:
  528. close(loopfd);
  529. error_close_memfd:
  530. close(memfd);
  531. error:
  532. errno = err;
  533. return -1;
  534. }
  535.  
  536. static void reset_loop_device(const char* loopname)
  537. {
  538. int loopfd = open(loopname, O_RDWR);
  539. if (loopfd == -1) {
  540. return;
  541. }
  542. if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
  543. }
  544. close(loopfd);
  545. }
  546.  
  547. static long syz_mount_image(volatile long fsarg, volatile long dir,
  548. volatile long flags, volatile long optsarg,
  549. volatile long change_dir,
  550. volatile unsigned long size, volatile long image)
  551. {
  552. unsigned char* data = (unsigned char*)image;
  553. int res = -1, err = 0, need_loop_device = !!size;
  554. char* mount_opts = (char*)optsarg;
  555. char* target = (char*)dir;
  556. char* fs = (char*)fsarg;
  557. char* source = NULL;
  558. char loopname[64];
  559. if (need_loop_device) {
  560. int loopfd;
  561. memset(loopname, 0, sizeof(loopname));
  562. snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
  563. if (setup_loop_device(data, size, loopname, &loopfd) == -1)
  564. return -1;
  565. close(loopfd);
  566. source = loopname;
  567. }
  568. mkdir(target, 0777);
  569. char opts[256];
  570. memset(opts, 0, sizeof(opts));
  571. if (strlen(mount_opts) > (sizeof(opts) - 32)) {
  572. }
  573. strncpy(opts, mount_opts, sizeof(opts) - 32);
  574. if (strcmp(fs, "iso9660") == 0) {
  575. flags |= MS_RDONLY;
  576. } else if (strncmp(fs, "ext", 3) == 0) {
  577. bool has_remount_ro = false;
  578. char* remount_ro_start = strstr(opts, "errors=remount-ro");
  579. if (remount_ro_start != NULL) {
  580. char after = *(remount_ro_start + strlen("errors=remount-ro"));
  581. char before = remount_ro_start == opts ? '\0' : *(remount_ro_start - 1);
  582. has_remount_ro = ((before == '\0' || before == ',') &&
  583. (after == '\0' || after == ','));
  584. }
  585. if (strstr(opts, "errors=panic") || !has_remount_ro)
  586. strcat(opts, ",errors=continue");
  587. } else if (strcmp(fs, "xfs") == 0) {
  588. strcat(opts, ",nouuid");
  589. }
  590. res = mount(source, target, fs, flags, opts);
  591. if (res == -1) {
  592. err = errno;
  593. goto error_clear_loop;
  594. }
  595. res = open(target, O_RDONLY | O_DIRECTORY);
  596. if (res == -1) {
  597. err = errno;
  598. goto error_clear_loop;
  599. }
  600. if (change_dir) {
  601. res = chdir(target);
  602. if (res == -1) {
  603. err = errno;
  604. }
  605. }
  606.  
  607. error_clear_loop:
  608. if (need_loop_device)
  609. reset_loop_device(loopname);
  610. errno = err;
  611. return res;
  612. }
  613.  
  614. #define FS_IOC_SETFLAGS _IOW('f', 2, long)
  615. static void remove_dir(const char* dir)
  616. {
  617. int iter = 0;
  618. DIR* dp = 0;
  619. retry:
  620. while (umount2(dir, MNT_DETACH | UMOUNT_NOFOLLOW) == 0) {
  621. }
  622. dp = opendir(dir);
  623. if (dp == NULL) {
  624. if (errno == EMFILE) {
  625. exit(1);
  626. }
  627. exit(1);
  628. }
  629. struct dirent* ep = 0;
  630. while ((ep = readdir(dp))) {
  631. if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
  632. continue;
  633. char filename[FILENAME_MAX];
  634. snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
  635. while (umount2(filename, MNT_DETACH | UMOUNT_NOFOLLOW) == 0) {
  636. }
  637. struct stat st;
  638. if (lstat(filename, &st))
  639. exit(1);
  640. if (S_ISDIR(st.st_mode)) {
  641. remove_dir(filename);
  642. continue;
  643. }
  644. int i;
  645. for (i = 0;; i++) {
  646. if (unlink(filename) == 0)
  647. break;
  648. if (errno == EPERM) {
  649. int fd = open(filename, O_RDONLY);
  650. if (fd != -1) {
  651. long flags = 0;
  652. if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
  653. }
  654. close(fd);
  655. continue;
  656. }
  657. }
  658. if (errno == EROFS) {
  659. break;
  660. }
  661. if (errno != EBUSY || i > 100)
  662. exit(1);
  663. if (umount2(filename, MNT_DETACH | UMOUNT_NOFOLLOW))
  664. exit(1);
  665. }
  666. }
  667. closedir(dp);
  668. for (int i = 0;; i++) {
  669. if (rmdir(dir) == 0)
  670. break;
  671. if (i < 100) {
  672. if (errno == EPERM) {
  673. int fd = open(dir, O_RDONLY);
  674. if (fd != -1) {
  675. long flags = 0;
  676. if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
  677. }
  678. close(fd);
  679. continue;
  680. }
  681. }
  682. if (errno == EROFS) {
  683. break;
  684. }
  685. if (errno == EBUSY) {
  686. if (umount2(dir, MNT_DETACH | UMOUNT_NOFOLLOW))
  687. exit(1);
  688. continue;
  689. }
  690. if (errno == ENOTEMPTY) {
  691. if (iter < 100) {
  692. iter++;
  693. goto retry;
  694. }
  695. }
  696. }
  697. exit(1);
  698. }
  699. }
  700.  
  701. static void kill_and_wait(int pid, int* status)
  702. {
  703. kill(-pid, SIGKILL);
  704. kill(pid, SIGKILL);
  705. for (int i = 0; i < 100; i++) {
  706. if (waitpid(-1, status, WNOHANG | __WALL) == pid)
  707. return;
  708. usleep(1000);
  709. }
  710. DIR* dir = opendir("/sys/fs/fuse/connections");
  711. if (dir) {
  712. for (;;) {
  713. struct dirent* ent = readdir(dir);
  714. if (!ent)
  715. break;
  716. if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
  717. continue;
  718. char abort[300];
  719. snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
  720. ent->d_name);
  721. int fd = open(abort, O_WRONLY);
  722. if (fd == -1) {
  723. continue;
  724. }
  725. if (write(fd, abort, 1) < 0) {
  726. }
  727. close(fd);
  728. }
  729. closedir(dir);
  730. } else {
  731. }
  732. while (waitpid(-1, status, __WALL) != pid) {
  733. }
  734. }
  735.  
  736. static void reset_loop()
  737. {
  738. char buf[64];
  739. snprintf(buf, sizeof(buf), "/dev/loop%llu", procid);
  740. int loopfd = open(buf, O_RDWR);
  741. if (loopfd != -1) {
  742. ioctl(loopfd, LOOP_CLR_FD, 0);
  743. close(loopfd);
  744. }
  745. }
  746.  
  747. static void setup_test()
  748. {
  749. prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
  750. setpgrp();
  751. write_file("/proc/self/oom_score_adj", "1000");
  752. if (symlink("/dev/binderfs", "./binderfs")) {
  753. }
  754. }
  755.  
  756. struct thread_t {
  757. int created, call;
  758. event_t ready, done;
  759. };
  760.  
  761. static struct thread_t threads[16];
  762. static void execute_call(int call);
  763. static int running;
  764.  
  765. static void* thr(void* arg)
  766. {
  767. struct thread_t* th = (struct thread_t*)arg;
  768. for (;;) {
  769. event_wait(&th->ready);
  770. event_reset(&th->ready);
  771. execute_call(th->call);
  772. __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
  773. event_set(&th->done);
  774. }
  775. return 0;
  776. }
  777.  
  778. static void execute_one(void)
  779. {
  780. int i, call, thread;
  781. for (call = 0; call < 8; call++) {
  782. for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
  783. thread++) {
  784. struct thread_t* th = &threads[thread];
  785. if (!th->created) {
  786. th->created = 1;
  787. event_init(&th->ready);
  788. event_init(&th->done);
  789. event_set(&th->done);
  790. thread_start(thr, th);
  791. }
  792. if (!event_isset(&th->done))
  793. continue;
  794. event_reset(&th->done);
  795. th->call = call;
  796. __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
  797. event_set(&th->ready);
  798. if (call == 6)
  799. break;
  800. event_timedwait(&th->done, 50 + (call == 0 ? 4000 : 0));
  801. break;
  802. }
  803. }
  804. for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
  805. sleep_ms(1);
  806. }
  807.  
  808. static void execute_one(void);
  809.  
  810. #define WAIT_FLAGS __WALL
  811.  
  812. static void loop(void)
  813. {
  814. int iter = 0;
  815. for (;; iter++) {
  816. char cwdbuf[32];
  817. sprintf(cwdbuf, "./%d", iter);
  818. if (mkdir(cwdbuf, 0777))
  819. exit(1);
  820. reset_loop();
  821. int pid = fork();
  822. if (pid < 0)
  823. exit(1);
  824. if (pid == 0) {
  825. if (chdir(cwdbuf))
  826. exit(1);
  827. setup_test();
  828. execute_one();
  829. exit(0);
  830. }
  831. int status = 0;
  832. uint64_t start = current_time_ms();
  833. for (;;) {
  834. if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
  835. break;
  836. sleep_ms(1);
  837. if (current_time_ms() - start < 5000)
  838. continue;
  839. kill_and_wait(pid, &status);
  840. break;
  841. }
  842. remove_dir(cwdbuf);
  843. }
  844. }
  845.  
  846. uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
  847.  
  848. void execute_call(int call)
  849. {
  850. intptr_t res = 0;
  851. switch (call) {
  852. case 0:
  853. memcpy((void*)0x20000040, "ext4\000", 5);
  854. memcpy((void*)0x20000500, "./file1\000", 8);
  855. memcpy((void*)0x20000540, "errors=remount-ro", 17);
  856. *(uint8_t*)0x20000551 = 0x2c;
  857. memcpy((void*)0x20000552, "sysvgroups", 10);
  858. *(uint8_t*)0x2000055c = 0x2c;
  859. memcpy((void*)0x2000055d, "dioread_lock", 12);
  860. *(uint8_t*)0x20000569 = 0x2c;
  861. memcpy((void*)0x2000056a, "grpquota", 8);
  862. *(uint8_t*)0x20000572 = 0x2c;
  863. memcpy((void*)0x20000573, "noauto_da_alloc", 15);
  864. *(uint8_t*)0x20000582 = 0x2c;
  865. memcpy((void*)0x20000583, "resgid", 6);
  866. *(uint8_t*)0x20000589 = 0x3d;
  867. sprintf((char*)0x2000058a, "0x%016llx", (long long)0);
  868. *(uint8_t*)0x2000059c = 0x2c;
  869. memcpy((void*)0x2000059d, "barrier", 7);
  870. *(uint8_t*)0x200005a4 = 0x2c;
  871. memcpy((void*)0x200005a5, "auto_da_alloc", 13);
  872. *(uint8_t*)0x200005b2 = 0x2c;
  873. memcpy((void*)0x200005b3, "usrquota", 8);
  874. *(uint8_t*)0x200005bb = 0x2c;
  875. *(uint8_t*)0x200005bc = 0;
  876. memcpy(
  877. (void*)0x20001b00,
  878. "\x78\x9c\xec\xdd\xdf\x6b\x5b\xd7\x1d\x00\xf0\xef\xbd\xb6\xb2\xfc\x70"
  879. "\x66\x67\xdb\x43\x16\x58\x16\x96\x0c\x27\x6c\x91\xec\x78\x49\xcc\x1e"
  880. "\xb2\x0c\xc6\xf2\x14\xd8\x96\xbd\x67\x9e\x2d\x1b\x63\xd9\x32\x96\x9c"
  881. "\xc4\x26\x0c\x87\xfd\x01\x83\x31\xd6\x42\x9f\xfa\xd4\x97\x42\xff\x80"
  882. "\x42\xc9\x9f\x50\x0a\x81\xf6\xbd\xb4\xa5\xa5\xb4\x49\xfb\xd0\x87\xb6"
  883. "\x2a\x92\xae\xd2\xc4\x95\x62\x87\xc8\xbe\x60\x7f\x3e\x70\x7c\xcf\xb9"
  884. "\x57\xd2\xf7\x7b\x6c\x74\x75\xcf\xbd\xc7\xba\x01\xec\x5b\xa7\x22\xe2"
  885. "\x6a\x44\x0c\x44\xc4\xb9\x88\x18\xce\xd6\xa7\x59\xb9\xd6\x6c\x6c\xb4"
  886. "\x1f\xf7\xe8\xe1\xdd\xe9\x66\x49\xa2\xd1\xb8\xf1\x59\x12\x49\xb6\xae"
  887. "\xf3\x5a\x49\xb6\x3c\xd2\x7e\x4a\x1c\x8c\x88\xbf\x5d\x8b\xf8\x67\xf2"
  888. "\xc3\xb8\xb5\xb5\xf5\x85\xa9\x4a\xa5\xbc\x92\xb5\x4b\xf5\xc5\xe5\x52"
  889. "\x6d\x6d\xfd\xfc\xfc\xe2\xd4\x5c\x79\xae\xbc\x34\x31\x31\x7e\x69\xf2"
  890. "\xf2\xe4\xc5\xc9\xb1\xbe\xf4\x73\x24\x22\xae\xfc\xe9\xa3\xff\xff\xe7"
  891. "\xb5\x3f\x5f\x79\xeb\xb7\xb7\xdf\xbf\xf9\xc9\xd9\x7f\x35\xd3\x1a\xca"
  892. "\xb6\x3f\xd9\x8f\x7e\x6a\x77\xbd\xd0\xfa\x5d\x74\x0c\x46\xc4\xca\x4e"
  893. "\x04\xcb\xc1\x40\xb6\x2c\xe4\x9c\x07\x00\x00\xdb\xd3\x3c\xc6\xff\x49"
  894. "\x44\xfc\xaa\x75\xfc\x3f\x1c\x03\xad\xa3\x53\x00\x00\x00\x60\x2f\x69"
  895. "\xfc\x61\x28\xbe\x4e\x22\x1a\x00\x00\x00\xc0\x9e\x95\xb6\xe6\xc0\x26"
  896. "\x69\x31\x9b\x0b\x30\x14\x69\x5a\x2c\xb6\xe7\xf0\xfe\x2c\x0e\xa7\x95"
  897. "\x6a\xad\xfe\x9b\xd9\xea\xea\xd2\x4c\x7b\xae\xec\x48\x14\xd2\xd9\xf9"
  898. "\x4a\x79\x2c\x9b\x2b\x3c\x12\x85\xa4\xd9\x1e\xcf\xe6\xd8\x76\xda\x17"
  899. "\x36\xb5\x27\x22\xe2\x58\x44\xfc\x6f\xf8\x50\xab\x5d\x9c\xae\x56\x66"
  900. "\xf2\x3e\xf9\x01\x00\x00\x00\xfb\xc4\x91\x4d\xe3\xff\x2f\x87\xdb\xe3"
  901. "\x7f\x00\x00\x00\x60\x8f\x19\xc9\x3b\x01\x00\x00\x00\x60\xc7\x19\xff"
  902. "\x03\x00\x00\xc0\xde\x67\xfc\x0f\x00\x00\x00\x7b\xda\x5f\xae\x5f\x6f"
  903. "\x96\x46\xe7\xfe\xd7\x33\xb7\xd6\x56\x17\xaa\xb7\xce\xcf\x94\x6b\x0b"
  904. "\xc5\xc5\xd5\xe9\xe2\x74\x75\x65\xb9\x38\x57\xad\xce\xb5\xbe\xb3\x6f"
  905. "\x71\xab\xd7\xab\x54\xab\xcb\xbf\x8b\xa5\xd5\x3b\xa5\x7a\xb9\x56\x2f"
  906. "\xd5\xd6\xd6\x6f\x2e\x56\x57\x97\xea\x37\xe7\x9f\xba\x05\x36\x00\x00"
  907. "\x00\xb0\x8b\x8e\xfd\xf2\xfe\x7b\x49\x44\x6c\xfc\xfe\x50\xab\x34\x1d"
  908. "\xc8\x3b\x29\x60\x57\x24\xcf\xf3\xe0\x0f\x77\x2e\x0f\x60\xf7\x0d\xe4"
  909. "\x9d\x00\x90\x9b\xc1\xbc\x13\x00\x72\x53\xc8\x3b\x01\x20\x77\x5b\x9d"
  910. "\x07\xe8\x39\x79\xe7\xed\xfe\xe7\x02\x00\x00\xec\x8c\xd1\x9f\xf7\xbe"
  911. "\xfe\xef\xdc\x00\xec\x6d\x69\xde\x09\x00\x00\xbb\xce\xf5\x7f\xd8\xbf"
  912. "\x0a\x66\x00\xc2\xbe\xf7\xe3\x2d\xb6\xbf\xf8\xf5\xff\x46\xe3\xb9\x12"
  913. "\x02\x00\x00\xfa\x6e\xa8\x55\x92\xb4\x98\x5d\x0b\x1c\x8a\x34\x2d\x16"
  914. "\x23\x8e\xb6\x6e\x0b\x50\x48\x66\xe7\x2b\xe5\xb1\x6c\x7c\xf0\xee\x70"
  915. "\xe1\x47\xcd\xf6\x78\xeb\x99\xc9\xf3\xfd\xef\x30\x00\x00\x00\x00\x00"
  916. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x63\x8d"
  917. "\x46\x12\x0d\x00\x00\x00\x60\x4f\x8b\x48\x3f\x4e\x5a\xdf\xe6\x1f\x31"
  918. "\x3a\x7c\x66\x68\xf3\xf9\x81\x03\xc9\x57\xc3\xad\x65\x44\xdc\x7e\xe5"
  919. "\xc6\x4b\x77\xa6\xea\xf5\x95\xf1\xe6\xfa\xcf\x1f\xaf\xaf\xbf\x9c\xad"
  920. "\xbf\x90\xc7\x19\x0c\x00\x00\x00\x60\xb3\xce\x38\xbd\x33\x8e\x07\x00"
  921. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  922. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  923. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  924. "\x00\x00\x80\x7e\x7a\xf4\xf0\xee\x74\xa7\xec\x66\xdc\x4f\xff\x18\x11"
  925. "\x23\xdd\xe2\x0f\xc6\xc1\xd6\xf2\x60\x14\x22\xe2\xf0\x17\x49\x0c\x3e"
  926. "\xf1\xbc\x24\x22\x06\xfa\x10\x7f\xe3\x5e\x44\x1c\xef\x16\x3f\x69\xa6"
  927. "\x15\x23\x59\x16\xdd\xe2\x1f\xca\x31\x7e\x1a\x11\x47\xfa\x10\x1f\xf6"
  928. "\xb3\xfb\xcd\xfd\xcf\xd5\x6e\xef\xbf\x34\x4e\xb5\x96\xdd\xdf\x7f\x83"
  929. "\x59\x79\x51\xbd\xf7\x7f\xe9\xe3\xfd\xdf\x40\x8f\xfd\xcf\xd1\x6d\xc6"
  930. "\x38\xf1\xe0\x8d\x52\xcf\xf8\xf7\x22\x4e\x0c\x76\xdf\xff\x74\xe2\x27"
  931. "\x3d\xe2\x9f\xde\x66\xfc\x7f\xfc\x7d\x7d\xbd\xd7\xb6\xc6\xab\x11\xa3"
  932. "\x5d\x3f\x7f\x92\xa7\x62\x95\xea\x8b\xcb\xa5\xda\xda\xfa\xf9\xf9\xc5"
  933. "\xa9\xb9\xf2\x5c\x79\x69\x62\x62\xfc\xd2\xe4\xe5\xc9\x8b\x93\x63\xa5"
  934. "\xd9\xf9\x4a\x39\xfb\xd9\x35\xc6\x7f\x7f\xf1\xe6\xb7\xcf\xea\xff\xe1"
  935. "\x1e\xf1\x47\xb6\xe8\xff\x99\x6d\xf6\xff\x9b\x07\x77\x1e\xfe\xb4\x5d"
  936. "\x2d\x74\x8b\x7f\xf6\x74\xf7\xcf\xdf\xe3\x3d\xe2\xa7\xd9\x67\xdf\xaf"
  937. "\xb3\x7a\x73\xfb\x68\xa7\xbe\xd1\xae\x3f\xe9\xe4\xeb\xef\x9c\x7c\x56"
  938. "\xff\x67\x7a\xf4\x7f\xab\xbf\xff\xd9\x6d\xf6\xff\xdc\x5f\xff\xfd\xc1"
  939. "\x36\x1f\x0a\x00\xec\x82\xda\xda\xfa\xc2\x54\xa5\x52\x5e\x51\x51\x51"
  940. "\x51\x79\x5c\xc9\x7b\xcf\x04\x00\x00\xf4\xdb\xf7\x07\xfd\x79\x67\x02"
  941. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xd7"
  942. "\x6e\x7c\x9d\xd8\xe6\x98\x1b\xf9\x74\x15\x00\x00\x00\x00\x00\x00\x00"
  943. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  944. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  945. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  946. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  947. "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  948. "\x00\x00\xe0\x99\xbe\x0b\x00\x00\xff\xff\xf7\xa0\xd4\xed",
  949. 1204);
  950. syz_mount_image(/*fs=*/0x20000040, /*dir=*/0x20000500,
  951. /*flags=MS_REC|MS_NOATIME|0x100*/ 0x4500,
  952. /*opts=*/0x20000540, /*chdir=*/0x12, /*size=*/0x4b4,
  953. /*img=*/0x20001b00);
  954. break;
  955. case 1:
  956. memcpy((void*)0x200000c0, "./file1\000", 8);
  957. res = syscall(
  958. __NR_open, /*file=*/0x200000c0ul,
  959. /*flags=O_SYNC|O_NONBLOCK|O_NOCTTY|O_NOATIME|O_DIRECT|O_CREAT|0x2002*/
  960. 0x147942ul, /*mode=*/0ul);
  961. if (res != -1)
  962. r[0] = res;
  963. break;
  964. case 2:
  965. memcpy((void*)0x20000180, "./bus\000", 6);
  966. syscall(__NR_open, /*file=*/0x20000180ul,
  967. /*flags=O_TRUNC|O_SYNC|O_NOATIME|O_LARGEFILE|O_DIRECT|O_CREAT|0x3e*/
  968. 0x14d27eul, /*mode=*/0ul);
  969. break;
  970. case 3:
  971. memcpy((void*)0x20000380, "/dev/loop", 9);
  972. *(uint8_t*)0x20000389 = 0x30;
  973. *(uint8_t*)0x2000038a = 0;
  974. memcpy((void*)0x20000140, "./bus\000", 6);
  975. syscall(__NR_mount, /*src=*/0x20000380ul, /*dst=*/0x20000140ul,
  976. /*type=*/0ul, /*flags=MS_BIND*/ 0x1000ul, /*data=*/0ul);
  977. break;
  978. case 4:
  979. memcpy((void*)0x20000400, "./bus\000", 6);
  980. res = syscall(__NR_open, /*file=*/0x20000400ul,
  981. /*flags=O_SYNC|O_NOCTTY|O_NOATIME|O_RDWR|0x3c*/ 0x14113eul,
  982. /*mode=*/0ul);
  983. if (res != -1)
  984. r[1] = res;
  985. break;
  986. case 5:
  987. syscall(__NR_sendfile, /*fdout=*/r[0], /*fdin=*/r[1], /*off=*/0ul,
  988. /*count=*/0x8000005cul);
  989. break;
  990. case 6:
  991. syscall(__NR_write, /*fd=*/r[1], /*data=*/0x20000100ul,
  992. /*len=*/0x208e24bul);
  993. break;
  994. case 7:
  995. *(uint16_t*)0x20000080 = 0;
  996. *(uint16_t*)0x20000082 = 0;
  997. *(uint64_t*)0x20000088 = 0;
  998. *(uint64_t*)0x20000090 = 0x1ff7fdfd000;
  999. *(uint32_t*)0x20000098 = 0;
  1000. *(uint32_t*)0x2000009c = 0x48000000;
  1001. memset((void*)0x200000a0, 0, 16);
  1002. syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x40305829, /*arg=*/0x20000080ul);
  1003. break;
  1004. }
  1005. }
  1006. int main(void)
  1007. {
  1008. syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul,
  1009. /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  1010. /*offset=*/0ul);
  1011. syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
  1012. /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
  1013. /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  1014. /*offset=*/0ul);
  1015. syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
  1016. /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  1017. /*offset=*/0ul);
  1018. use_temporary_dir();
  1019. loop();
  1020. return 0;
  1021. }
  1022.  
Advertisement
Add Comment
Please, Sign In to add comment