Advertisement
zzqq0103

Untitled

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