Advertisement
Guest User

Untitled

a guest
Sep 5th, 2017
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.33 KB | None | 0 0
  1. // autogenerated by syzkaller (http://github.com/google/syzkaller)
  2.  
  3. #define _GNU_SOURCE
  4.  
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <sys/syscall.h>
  8. #include <unistd.h>
  9. #include <setjmp.h>
  10. #include <signal.h>
  11. #include <string.h>
  12. #include <errno.h>
  13. #include <stdarg.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <sys/stat.h>
  17. #include <errno.h>
  18. #include <sched.h>
  19. #include <signal.h>
  20. #include <stdarg.h>
  21. #include <stdbool.h>
  22. #include <stdio.h>
  23. #include <sys/prctl.h>
  24. #include <sys/resource.h>
  25. #include <sys/time.h>
  26. #include <sys/wait.h>
  27. #include <grp.h>
  28. #include <arpa/inet.h>
  29. #include <errno.h>
  30. #include <fcntl.h>
  31. #include <linux/if.h>
  32. #include <linux/if_ether.h>
  33. #include <linux/if_tun.h>
  34. #include <linux/ip.h>
  35. #include <linux/tcp.h>
  36. #include <net/if_arp.h>
  37. #include <stdarg.h>
  38. #include <stdbool.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <sys/ioctl.h>
  42. #include <sys/stat.h>
  43.  
  44. const int kFailStatus = 67;
  45. const int kRetryStatus = 69;
  46.  
  47. __attribute__((noreturn)) static void doexit(int status)
  48. {
  49. volatile unsigned i;
  50. syscall(__NR_exit_group, status);
  51. for (i = 0;; i++) {
  52. }
  53. }
  54.  
  55. __attribute__((noreturn)) static void fail(const char* msg, ...)
  56. {
  57. int e = errno;
  58. fflush(stdout);
  59. va_list args;
  60. va_start(args, msg);
  61. vfprintf(stderr, msg, args);
  62. va_end(args);
  63. fprintf(stderr, " (errno %d)\n", e);
  64. doexit((e == ENOMEM || e == EAGAIN) ? kRetryStatus : kFailStatus);
  65. }
  66.  
  67. static __thread int skip_segv;
  68. static __thread jmp_buf segv_env;
  69.  
  70. static void segv_handler(int sig, siginfo_t* info, void* uctx)
  71. {
  72. uintptr_t addr = (uintptr_t)info->si_addr;
  73. const uintptr_t prog_start = 1 << 20;
  74. const uintptr_t prog_end = 100 << 20;
  75. if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) {
  76. _longjmp(segv_env, 1);
  77. }
  78. doexit(sig);
  79. for (;;) {
  80. }
  81. }
  82.  
  83. static void install_segv_handler()
  84. {
  85. struct sigaction sa;
  86.  
  87. memset(&sa, 0, sizeof(sa));
  88. sa.sa_handler = SIG_IGN;
  89. syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
  90. syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
  91.  
  92. memset(&sa, 0, sizeof(sa));
  93. sa.sa_sigaction = segv_handler;
  94. sa.sa_flags = SA_NODEFER | SA_SIGINFO;
  95. sigaction(SIGSEGV, &sa, NULL);
  96. sigaction(SIGBUS, &sa, NULL);
  97. }
  98.  
  99. #define NONFAILING(...) { __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); if (_setjmp(segv_env) == 0) { __VA_ARGS__; } __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); }
  100.  
  101. static void use_temporary_dir()
  102. {
  103. char tmpdir_template[] = "./syzkaller.XXXXXX";
  104. char* tmpdir = mkdtemp(tmpdir_template);
  105. if (!tmpdir)
  106. fail("failed to mkdtemp");
  107. if (chmod(tmpdir, 0777))
  108. fail("failed to chmod");
  109. if (chdir(tmpdir))
  110. fail("failed to chdir");
  111. }
  112.  
  113. static void vsnprintf_check(char* str, size_t size, const char* format, va_list args)
  114. {
  115. int rv;
  116.  
  117. rv = vsnprintf(str, size, format, args);
  118. if (rv < 0)
  119. fail("tun: snprintf failed");
  120. if ((size_t)rv >= size)
  121. fail("tun: string '%s...' doesn't fit into buffer", str);
  122. }
  123.  
  124. static void snprintf_check(char* str, size_t size, const char* format, ...)
  125. {
  126. va_list args;
  127.  
  128. va_start(args, format);
  129. vsnprintf_check(str, size, format, args);
  130. va_end(args);
  131. }
  132.  
  133. #define COMMAND_MAX_LEN 128
  134.  
  135. static void execute_command(const char* format, ...)
  136. {
  137. va_list args;
  138. char command[COMMAND_MAX_LEN];
  139. int rv;
  140.  
  141. va_start(args, format);
  142.  
  143. vsnprintf_check(command, sizeof(command), format, args);
  144. rv = system(command);
  145. if (rv != 0)
  146. fail("tun: command \"%s\" failed with code %d", &command[0], rv);
  147.  
  148. va_end(args);
  149. }
  150.  
  151. static int tunfd = -1;
  152.  
  153. #define SYZ_TUN_MAX_PACKET_SIZE 1000
  154.  
  155. #define MAX_PIDS 32
  156. #define ADDR_MAX_LEN 32
  157.  
  158. #define LOCAL_MAC "aa:aa:aa:aa:aa:%02hx"
  159. #define REMOTE_MAC "bb:bb:bb:bb:bb:%02hx"
  160.  
  161. #define LOCAL_IPV4 "172.20.%d.170"
  162. #define REMOTE_IPV4 "172.20.%d.187"
  163.  
  164. #define LOCAL_IPV6 "fe80::%02hxaa"
  165. #define REMOTE_IPV6 "fe80::%02hxbb"
  166.  
  167. static void initialize_tun(uint64_t pid)
  168. {
  169. if (pid >= MAX_PIDS)
  170. fail("tun: no more than %d executors", MAX_PIDS);
  171. int id = pid;
  172.  
  173. tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
  174. if (tunfd == -1)
  175. fail("tun: can't open /dev/net/tun");
  176.  
  177. char iface[IFNAMSIZ];
  178. snprintf_check(iface, sizeof(iface), "syz%d", id);
  179.  
  180. struct ifreq ifr;
  181. memset(&ifr, 0, sizeof(ifr));
  182. strncpy(ifr.ifr_name, iface, IFNAMSIZ);
  183. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  184. if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0)
  185. fail("tun: ioctl(TUNSETIFF) failed");
  186.  
  187. char local_mac[ADDR_MAX_LEN];
  188. snprintf_check(local_mac, sizeof(local_mac), LOCAL_MAC, id);
  189. char remote_mac[ADDR_MAX_LEN];
  190. snprintf_check(remote_mac, sizeof(remote_mac), REMOTE_MAC, id);
  191.  
  192. char local_ipv4[ADDR_MAX_LEN];
  193. snprintf_check(local_ipv4, sizeof(local_ipv4), LOCAL_IPV4, id);
  194. char remote_ipv4[ADDR_MAX_LEN];
  195. snprintf_check(remote_ipv4, sizeof(remote_ipv4), REMOTE_IPV4, id);
  196.  
  197. char local_ipv6[ADDR_MAX_LEN];
  198. snprintf_check(local_ipv6, sizeof(local_ipv6), LOCAL_IPV6, id);
  199. char remote_ipv6[ADDR_MAX_LEN];
  200. snprintf_check(remote_ipv6, sizeof(remote_ipv6), REMOTE_IPV6, id);
  201.  
  202. execute_command("sysctl -w net.ipv6.conf.%s.accept_dad=0", iface);
  203.  
  204. execute_command("sysctl -w net.ipv6.conf.%s.router_solicitations=0", iface);
  205.  
  206. execute_command("ip link set dev %s address %s", iface, local_mac);
  207. execute_command("ip addr add %s/24 dev %s", local_ipv4, iface);
  208. execute_command("ip -6 addr add %s/120 dev %s", local_ipv6, iface);
  209. execute_command("ip neigh add %s lladdr %s dev %s nud permanent", remote_ipv4, remote_mac, iface);
  210. execute_command("ip -6 neigh add %s lladdr %s dev %s nud permanent", remote_ipv6, remote_mac, iface);
  211. execute_command("ip link set dev %s up", iface);
  212. }
  213.  
  214. static void setup_tun(uint64_t pid, bool enable_tun)
  215. {
  216. if (enable_tun)
  217. initialize_tun(pid);
  218. }
  219.  
  220. static void loop();
  221.  
  222. static void sandbox_common()
  223. {
  224. prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
  225. setpgrp();
  226. setsid();
  227.  
  228. struct rlimit rlim;
  229. rlim.rlim_cur = rlim.rlim_max = 128 << 20;
  230. setrlimit(RLIMIT_AS, &rlim);
  231. rlim.rlim_cur = rlim.rlim_max = 8 << 20;
  232. setrlimit(RLIMIT_MEMLOCK, &rlim);
  233. rlim.rlim_cur = rlim.rlim_max = 1 << 20;
  234. setrlimit(RLIMIT_FSIZE, &rlim);
  235. rlim.rlim_cur = rlim.rlim_max = 1 << 20;
  236. setrlimit(RLIMIT_STACK, &rlim);
  237. rlim.rlim_cur = rlim.rlim_max = 0;
  238. setrlimit(RLIMIT_CORE, &rlim);
  239.  
  240. unshare(CLONE_NEWNS);
  241. unshare(CLONE_NEWIPC);
  242. unshare(CLONE_IO);
  243. }
  244.  
  245. static int do_sandbox_setuid(int executor_pid, bool enable_tun)
  246. {
  247. int pid = fork();
  248. if (pid)
  249. return pid;
  250.  
  251. sandbox_common();
  252. setup_tun(executor_pid, enable_tun);
  253.  
  254. const int nobody = 65534;
  255. if (setgroups(0, NULL))
  256. fail("failed to setgroups");
  257. if (syscall(SYS_setresgid, nobody, nobody, nobody))
  258. fail("failed to setresgid");
  259. if (syscall(SYS_setresuid, nobody, nobody, nobody))
  260. fail("failed to setresuid");
  261.  
  262. prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
  263.  
  264. loop();
  265. doexit(1);
  266. }
  267.  
  268. long r[4];
  269. void loop()
  270. {
  271. syscall(SYS_write, 1, "executing program\n", strlen("executing program\n"));
  272. memset(r, -1, sizeof(r));
  273. r[0] = syscall(__NR_mmap, 0x20000000ul, 0x12000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul);
  274. r[1] = syscall(__NR_pipe, 0x20011ff8ul);
  275. if (r[1] != -1)
  276. NONFAILING(r[2] = *(uint32_t*)0x20011ff8);
  277. r[3] = syscall(__NR_fcntl, r[2], 0x407ul, 0x0ul);
  278. }
  279.  
  280. int main()
  281. {
  282. install_segv_handler();
  283. use_temporary_dir();
  284. int pid = do_sandbox_setuid(0, true);
  285. int status = 0;
  286. while (waitpid(pid, &status, __WALL) != pid) {}
  287. return 0;
  288. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement