Advertisement
Guest User

Untitled

a guest
Jan 27th, 2022
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.40 KB | None | 0 0
  1. Syzkaller hit 'memory leak in prepare_creds' bug.
  2.  
  3. executing program
  4. executing program
  5. BUG: memory leak
  6. unreferenced object 0xffff88800de0f400 (size 176):
  7. comm "syz-executor221", pid 232, jiffies 4294806347 (age 19.226s)
  8. hex dump (first 32 bytes):
  9. 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  10. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  11. backtrace:
  12. [<00000000d7267485>] prepare_creds+0x2b/0x6f0 kernel/cred.c:260
  13. [<00000000944a3848>] copy_creds+0x72/0x930 kernel/cred.c:365
  14. [<000000002be529b9>] copy_process+0x1091/0x6e80 kernel/fork.c:2063
  15. [<00000000c9ac28da>] kernel_clone+0xe7/0x1050 kernel/fork.c:2582
  16. [<0000000094b79658>] __do_sys_clone+0xc8/0x110 kernel/fork.c:2699
  17. [<00000000ccb88a3f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  18. [<00000000ccb88a3f>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
  19. [<000000007042bd37>] entry_SYSCALL_64_after_hwframe+0x44/0xae
  20.  
  21. BUG: memory leak
  22. unreferenced object 0xffff88800e436900 (size 32):
  23. comm "syz-executor221", pid 232, jiffies 4294806347 (age 19.226s)
  24. hex dump (first 32 bytes):
  25. 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
  26. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  27. backtrace:
  28. [<0000000001439cb7>] slab_alloc_node mm/slub.c:3234 [inline]
  29. [<0000000001439cb7>] slab_alloc mm/slub.c:3242 [inline]
  30. [<0000000001439cb7>] __kmalloc+0x166/0x350 mm/slub.c:4419
  31. [<0000000014e9e082>] kmalloc include/linux/slab.h:595 [inline]
  32. [<0000000014e9e082>] kzalloc include/linux/slab.h:724 [inline]
  33. [<0000000014e9e082>] lsm_cred_alloc security/security.c:537 [inline]
  34. [<0000000014e9e082>] security_prepare_creds+0x10a/0x180 security/security.c:1692
  35. [<000000009629e28f>] prepare_creds+0x505/0x6f0 kernel/cred.c:291
  36. [<00000000944a3848>] copy_creds+0x72/0x930 kernel/cred.c:365
  37. [<000000002be529b9>] copy_process+0x1091/0x6e80 kernel/fork.c:2063
  38. [<00000000c9ac28da>] kernel_clone+0xe7/0x1050 kernel/fork.c:2582
  39. [<0000000094b79658>] __do_sys_clone+0xc8/0x110 kernel/fork.c:2699
  40. [<00000000ccb88a3f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  41. [<00000000ccb88a3f>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
  42. [<000000007042bd37>] entry_SYSCALL_64_after_hwframe+0x44/0xae
  43.  
  44. BUG: memory leak
  45. unreferenced object 0xffff88800db5b000 (size 1024):
  46. comm "syz-executor221", pid 234, jiffies 4294806357 (age 19.216s)
  47. hex dump (first 32 bytes):
  48. 60 ec 4f 84 ff ff ff ff 01 00 00 00 00 00 00 00 `.O.............
  49. 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N..........
  50. backtrace:
  51. [<000000001eb98443>] slab_alloc_node mm/slub.c:3234 [inline]
  52. [<000000001eb98443>] slab_alloc mm/slub.c:3242 [inline]
  53. [<000000001eb98443>] kmem_cache_alloc_trace+0x1b1/0x410 mm/slub.c:3259
  54. [<0000000019cd7692>] kmalloc include/linux/slab.h:590 [inline]
  55. [<0000000019cd7692>] kzalloc include/linux/slab.h:724 [inline]
  56. [<0000000019cd7692>] __fsnotify_alloc_group+0x87/0x2e0 fs/notify/group.c:119
  57. [<00000000c784e765>] inotify_new_group fs/notify/inotify/inotify_user.c:639 [inline]
  58. [<00000000c784e765>] do_inotify_init+0x44/0x5f0 fs/notify/inotify/inotify_user.c:687
  59. [<0000000092552d66>] __do_sys_inotify_init1 fs/notify/inotify/inotify_user.c:701 [inline]
  60. [<0000000092552d66>] __se_sys_inotify_init1 fs/notify/inotify/inotify_user.c:699 [inline]
  61. [<0000000092552d66>] __x64_sys_inotify_init1+0x2d/0x40 fs/notify/inotify/inotify_user.c:699
  62. [<00000000ccb88a3f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  63. [<00000000ccb88a3f>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
  64. [<000000007042bd37>] entry_SYSCALL_64_after_hwframe+0x44/0xae
  65.  
  66. BUG: memory leak
  67. unreferenced object 0xffff88800d034e80 (size 32):
  68. comm "syz-executor221", pid 234, jiffies 4294806357 (age 19.216s)
  69. hex dump (first 32 bytes):
  70. 80 4e 03 0d 80 88 ff ff 80 4e 03 0d 80 88 ff ff .N.......N......
  71. 00 40 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 .@..............
  72. backtrace:
  73. [<000000001eb98443>] slab_alloc_node mm/slub.c:3234 [inline]
  74. [<000000001eb98443>] slab_alloc mm/slub.c:3242 [inline]
  75. [<000000001eb98443>] kmem_cache_alloc_trace+0x1b1/0x410 mm/slub.c:3259
  76. [<00000000a23d1d08>] kmalloc include/linux/slab.h:590 [inline]
  77. [<00000000a23d1d08>] inotify_new_group fs/notify/inotify/inotify_user.c:643 [inline]
  78. [<00000000a23d1d08>] do_inotify_init+0x9d/0x5f0 fs/notify/inotify/inotify_user.c:687
  79. [<0000000092552d66>] __do_sys_inotify_init1 fs/notify/inotify/inotify_user.c:701 [inline]
  80. [<0000000092552d66>] __se_sys_inotify_init1 fs/notify/inotify/inotify_user.c:699 [inline]
  81. [<0000000092552d66>] __x64_sys_inotify_init1+0x2d/0x40 fs/notify/inotify/inotify_user.c:699
  82. [<00000000ccb88a3f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  83. [<00000000ccb88a3f>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
  84. [<000000007042bd37>] entry_SYSCALL_64_after_hwframe+0x44/0xae
  85.  
  86. BUG: memory leak
  87. unreferenced object 0xffff88800e0aaf00 (size 464):
  88. comm "syz-executor221", pid 234, jiffies 4294806363 (age 19.210s)
  89. hex dump (first 32 bytes):
  90. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  91. a0 a4 e5 07 80 88 ff ff 48 ea 81 1a 80 88 ff ff ........H.......
  92. backtrace:
  93. [<00000000cec63102>] kmem_cache_zalloc include/linux/slab.h:714 [inline]
  94. [<00000000cec63102>] __alloc_file+0x21/0x240 fs/file_table.c:101
  95. [<000000001782d092>] alloc_empty_file+0x6d/0x170 fs/file_table.c:150
  96. [<00000000f746e44b>] alloc_file+0x59/0x590 fs/file_table.c:192
  97. [<00000000dc119180>] alloc_file_pseudo+0x16a/0x250 fs/file_table.c:232
  98. [<00000000a53ee9f9>] __anon_inode_getfile+0x137/0x3d0 fs/anon_inodes.c:109
  99. [<00000000aa7e1319>] __anon_inode_getfd+0x61/0xc0 fs/anon_inodes.c:194
  100. [<00000000fbe857a6>] do_inotify_init+0x493/0x5f0 fs/notify/inotify/inotify_user.c:691
  101. [<0000000092552d66>] __do_sys_inotify_init1 fs/notify/inotify/inotify_user.c:701 [inline]
  102. [<0000000092552d66>] __se_sys_inotify_init1 fs/notify/inotify/inotify_user.c:699 [inline]
  103. [<0000000092552d66>] __x64_sys_inotify_init1+0x2d/0x40 fs/notify/inotify/inotify_user.c:699
  104. [<00000000ccb88a3f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
  105. [<00000000ccb88a3f>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
  106. [<000000007042bd37>] entry_SYSCALL_64_after_hwframe+0x44/0xae
  107.  
  108.  
  109.  
  110. Syzkaller reproducer:
  111. # {Threaded:true Repeat:true RepeatTimes:0 Procs:1 Slowdown:1 Sandbox: Leak:true NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false VhciInjection:false Wifi:false IEEE802154:false Sysctl:false UseTmpDir:false HandleSegv:false Repro:false Trace:false LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
  112. inotify_init1(0x0) (rerun: 64)
  113. r0 = fsopen(&(0x7f0000000000)='sysfs\x00', 0x0)
  114. close_range(r0, 0xffffffffffffffff, 0x2)
  115.  
  116.  
  117. C reproducer:
  118. // autogenerated by syzkaller (https://github.com/google/syzkaller)
  119.  
  120. #define _GNU_SOURCE
  121.  
  122. #include <dirent.h>
  123. #include <endian.h>
  124. #include <errno.h>
  125. #include <fcntl.h>
  126. #include <pthread.h>
  127. #include <signal.h>
  128. #include <stdarg.h>
  129. #include <stdbool.h>
  130. #include <stdint.h>
  131. #include <stdio.h>
  132. #include <stdlib.h>
  133. #include <string.h>
  134. #include <sys/prctl.h>
  135. #include <sys/stat.h>
  136. #include <sys/syscall.h>
  137. #include <sys/types.h>
  138. #include <sys/wait.h>
  139. #include <time.h>
  140. #include <unistd.h>
  141.  
  142. #include <linux/futex.h>
  143.  
  144. #ifndef __NR_close_range
  145. #define __NR_close_range 436
  146. #endif
  147.  
  148. #ifndef SYS_gettid
  149. #error "SYS_gettid unavailable on this system"
  150. #endif
  151.  
  152. #define gettid() ((pid_t)syscall(SYS_gettid))
  153.  
  154. static void sleep_ms(uint64_t ms)
  155. {
  156. usleep(ms * 1000);
  157. }
  158.  
  159. static uint64_t current_time_ms(void)
  160. {
  161. struct timespec ts;
  162. if (clock_gettime(CLOCK_MONOTONIC, &ts))
  163. exit(1);
  164. return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
  165. }
  166.  
  167. static void thread_start(void* (*fn)(void*), void* arg)
  168. {
  169. pid_t pid = getpid();
  170. pid_t tid = gettid();
  171.  
  172. pthread_t th;
  173. pthread_attr_t attr;
  174. pthread_attr_init(&attr);
  175. pthread_attr_setstacksize(&attr, 128 << 10);
  176. int i = 0;
  177. for (; i < 100; i++) {
  178. if (pthread_create(&th, &attr, fn, arg) == 0) {
  179. pthread_attr_destroy(&attr);
  180. printf("%d %d created thread\n", pid, tid);
  181. return;
  182. }
  183. if (errno == EAGAIN) {
  184. usleep(50);
  185. continue;
  186. }
  187. break;
  188. }
  189. exit(1);
  190. }
  191.  
  192. typedef struct {
  193. int state;
  194. } event_t;
  195.  
  196. static void event_init(event_t* ev)
  197. {
  198. ev->state = 0;
  199. }
  200.  
  201. static void event_reset(event_t* ev)
  202. {
  203. ev->state = 0;
  204. }
  205.  
  206. static void event_set(event_t* ev)
  207. {
  208. if (ev->state)
  209. exit(1);
  210. __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
  211. syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
  212. }
  213.  
  214. static void event_wait(event_t* ev)
  215. {
  216. while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
  217. syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
  218. }
  219.  
  220. static int event_isset(event_t* ev)
  221. {
  222. return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
  223. }
  224.  
  225. static int event_timedwait(event_t* ev, uint64_t timeout)
  226. {
  227. uint64_t start = current_time_ms();
  228. uint64_t now = start;
  229. for (;;) {
  230. uint64_t remain = timeout - (now - start);
  231. struct timespec ts;
  232. ts.tv_sec = remain / 1000;
  233. ts.tv_nsec = (remain % 1000) * 1000 * 1000;
  234. syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
  235. if (__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
  236. return 1;
  237. now = current_time_ms();
  238. if (now - start > timeout)
  239. return 0;
  240. }
  241. }
  242.  
  243. static bool write_file(const char* file, const char* what, ...)
  244. {
  245. char buf[1024];
  246. va_list args;
  247. va_start(args, what);
  248. vsnprintf(buf, sizeof(buf), what, args);
  249. va_end(args);
  250. buf[sizeof(buf) - 1] = 0;
  251. int len = strlen(buf);
  252. int fd = open(file, O_WRONLY | O_CLOEXEC);
  253. if (fd == -1)
  254. return false;
  255. if (write(fd, buf, len) != len) {
  256. int err = errno;
  257. close(fd);
  258. errno = err;
  259. return false;
  260. }
  261. close(fd);
  262. return true;
  263. }
  264.  
  265. static void kill_and_wait(int pid, int* status)
  266. {
  267. kill(-pid, SIGKILL);
  268. kill(pid, SIGKILL);
  269. for (int i = 0; i < 100; i++) {
  270. if (waitpid(-1, status, WNOHANG | __WALL) == pid)
  271. return;
  272. usleep(1000);
  273. }
  274. DIR* dir = opendir("/sys/fs/fuse/connections");
  275. if (dir) {
  276. for (;;) {
  277. struct dirent* ent = readdir(dir);
  278. if (!ent)
  279. break;
  280. if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
  281. continue;
  282. char abort[300];
  283. snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name);
  284. int fd = open(abort, O_WRONLY);
  285. if (fd == -1) {
  286. continue;
  287. }
  288. if (write(fd, abort, 1) < 0) {
  289. }
  290. close(fd);
  291. }
  292. closedir(dir);
  293. } else {
  294. }
  295. while (waitpid(-1, status, __WALL) != pid) {
  296. }
  297. }
  298.  
  299. static void setup_test()
  300. {
  301. prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
  302. setpgrp();
  303. write_file("/proc/self/oom_score_adj", "1000");
  304. }
  305.  
  306. #define KMEMLEAK_FILE "/sys/kernel/debug/kmemleak"
  307.  
  308. static void setup_leak()
  309. {
  310. if (!write_file(KMEMLEAK_FILE, "scan"))
  311. exit(1);
  312. sleep(5);
  313. if (!write_file(KMEMLEAK_FILE, "scan"))
  314. exit(1);
  315. if (!write_file(KMEMLEAK_FILE, "clear"))
  316. exit(1);
  317. }
  318.  
  319. static void check_leaks(void)
  320. {
  321. int fd = open(KMEMLEAK_FILE, O_RDWR);
  322. if (fd == -1)
  323. exit(1);
  324. uint64_t start = current_time_ms();
  325. if (write(fd, "scan", 4) != 4)
  326. exit(1);
  327. sleep(1);
  328. while (current_time_ms() - start < 4 * 1000)
  329. sleep(1);
  330. if (write(fd, "scan", 4) != 4)
  331. exit(1);
  332. static char buf[128 << 10];
  333. ssize_t n = read(fd, buf, sizeof(buf) - 1);
  334. if (n < 0)
  335. exit(1);
  336. int nleaks = 0;
  337. if (n != 0) {
  338. sleep(1);
  339. if (write(fd, "scan", 4) != 4)
  340. exit(1);
  341. if (lseek(fd, 0, SEEK_SET) < 0)
  342. exit(1);
  343. n = read(fd, buf, sizeof(buf) - 1);
  344. if (n < 0)
  345. exit(1);
  346. buf[n] = 0;
  347. char* pos = buf;
  348. char* end = buf + n;
  349. while (pos < end) {
  350. char* next = strstr(pos + 1, "unreferenced object");
  351. if (!next)
  352. next = end;
  353. char prev = *next;
  354. *next = 0;
  355. fprintf(stderr, "BUG: memory leak\n%s\n", pos);
  356. *next = prev;
  357. pos = next;
  358. nleaks++;
  359. }
  360. }
  361. if (write(fd, "clear", 5) != 5)
  362. exit(1);
  363. close(fd);
  364. if (nleaks)
  365. exit(1);
  366. }
  367.  
  368. struct thread_t {
  369. int created, call;
  370. event_t ready, done;
  371. };
  372.  
  373. static struct thread_t threads[16];
  374. static void execute_call(int call);
  375. static int running;
  376.  
  377. static void* thr(void* arg)
  378. {
  379. struct thread_t* th = (struct thread_t*)arg;
  380. for (;;) {
  381. event_wait(&th->ready);
  382. event_reset(&th->ready);
  383. execute_call(th->call);
  384. __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
  385. event_set(&th->done);
  386. }
  387. return 0;
  388. }
  389.  
  390. static void execute_one(void)
  391. {
  392. sleep_ms(100);
  393. int i, call, thread;
  394. for (call = 0; call < 2; call++) {
  395. for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
  396. struct thread_t* th = &threads[thread];
  397. if (!th->created) {
  398. th->created = 1;
  399. event_init(&th->ready);
  400. event_init(&th->done);
  401. event_set(&th->done);
  402. thread_start(thr, th);
  403. }
  404. if (!event_isset(&th->done))
  405. continue;
  406. event_reset(&th->done);
  407. th->call = call;
  408. __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
  409. event_set(&th->ready);
  410. event_timedwait(&th->done, 50);
  411. break;
  412. }
  413. }
  414. for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
  415. sleep_ms(1);
  416. }
  417.  
  418. static void execute_one(void);
  419.  
  420. #define WAIT_FLAGS __WALL
  421.  
  422. static void loop(void)
  423. {
  424. pid_t parentPID = getpid();
  425. pid_t parentTID = gettid();
  426. int iter = 0;
  427. for (;; iter++) {
  428. printf("%d %d forking\n", parentPID, parentTID);
  429. int pid = fork();
  430. if (pid < 0)
  431. exit(1);
  432. if (pid == 0) {
  433. setup_test();
  434. execute_one();
  435. exit(0);
  436. }
  437. printf("%d %d forked child %d\n", parentPID, parentTID, pid);
  438. int status = 0;
  439. uint64_t start = current_time_ms();
  440. for (;;) {
  441. if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
  442. break;
  443. sleep_ms(1);
  444. if (current_time_ms() - start < 5000)
  445. continue;
  446. kill_and_wait(pid, &status);
  447. break;
  448. }
  449. printf("%d %d checking leak after executor exited\n", parentPID, parentTID);
  450. check_leaks();
  451. }
  452. }
  453.  
  454. uint64_t r[1] = {0xffffffffffffffff};
  455.  
  456. void execute_call(int call)
  457. {
  458. pid_t pid = getpid();
  459. pid_t tid = gettid();
  460.  
  461. intptr_t res = 0;
  462. switch (call) {
  463. case 0:
  464. printf("%d %d pipe2\n", pid, tid);
  465. res = syscall(__NR_pipe2, 0x20000080ul, 0ul);
  466. {
  467. int i;
  468. for(i = 0; i < 64 /* 32 also triggers the bug, but 16 doesn't */; i++) {
  469. syscall(__NR_pipe2, 0x20000080ul, 0ul);
  470. }
  471. }
  472. if (res != -1)
  473. r[0] = *(uint32_t*)0x20000080;
  474. break;
  475. case 1:
  476. printf("%d %d close_range\n", pid, tid);
  477. syscall(__NR_close_range, r[0], -1, 2ul /* CLOSE_RANGE_UNSHARE */);
  478. break;
  479. }
  480.  
  481. }
  482.  
  483. int main(void)
  484. {
  485. syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  486. syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  487. syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  488. setup_leak();
  489. printf("%d %d starting loop\n", getpid(), gettid());
  490. loop();
  491. return 0;
  492. }
  493.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement