Syzkaller hit 'memory leak in prepare_creds' bug. executing program executing program BUG: memory leak unreferenced object 0xffff88800c9b7400 (size 176): comm "syz-executor641", pid 271, jiffies 4294826055 (age 23.828s) hex dump (first 32 bytes): 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000062ba1a5c>] prepare_creds+0x2b/0x6f0 kernel/cred.c:260 [<0000000046e9bfe2>] copy_creds+0x72/0x930 kernel/cred.c:365 [<00000000c89ab07b>] copy_process+0x107e/0x6cb0 kernel/fork.c:2034 [<00000000b227338d>] kernel_clone+0xe7/0xa60 kernel/fork.c:2557 [<00000000319afd18>] __do_sys_clone+0xc8/0x110 kernel/fork.c:2674 [<0000000053cb0d43>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000053cb0d43>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 [<0000000094dc90c0>] entry_SYSCALL_64_after_hwframe+0x44/0xae BUG: memory leak unreferenced object 0xffff88800cd848c0 (size 32): comm "syz-executor641", pid 271, jiffies 4294826055 (age 23.828s) hex dump (first 32 bytes): 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000247b56d8>] kmalloc include/linux/slab.h:586 [inline] [<00000000247b56d8>] kzalloc include/linux/slab.h:715 [inline] [<00000000247b56d8>] lsm_cred_alloc security/security.c:537 [inline] [<00000000247b56d8>] security_prepare_creds+0x10a/0x180 security/security.c:1684 [<000000002ee96022>] prepare_creds+0x505/0x6f0 kernel/cred.c:291 [<0000000046e9bfe2>] copy_creds+0x72/0x930 kernel/cred.c:365 [<00000000c89ab07b>] copy_process+0x107e/0x6cb0 kernel/fork.c:2034 [<00000000b227338d>] kernel_clone+0xe7/0xa60 kernel/fork.c:2557 [<00000000319afd18>] __do_sys_clone+0xc8/0x110 kernel/fork.c:2674 [<0000000053cb0d43>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000053cb0d43>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 [<0000000094dc90c0>] entry_SYSCALL_64_after_hwframe+0x44/0xae BUG: memory leak unreferenced object 0xffff88800dca63c0 (size 224): comm "syz-executor641", pid 271, jiffies 4294826056 (age 23.827s) hex dump (first 32 bytes): 02 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de .............N.. ff ff ff ff 00 00 00 00 ff ff ff ff ff ff ff ff ................ backtrace: [<0000000092e17b65>] alloc_pid+0xcd/0xd80 kernel/pid.c:180 [<00000000400c7234>] copy_process+0x3cf4/0x6cb0 kernel/fork.c:2182 [<00000000b227338d>] kernel_clone+0xe7/0xa60 kernel/fork.c:2557 [<00000000319afd18>] __do_sys_clone+0xc8/0x110 kernel/fork.c:2674 [<0000000053cb0d43>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000053cb0d43>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 [<0000000094dc90c0>] entry_SYSCALL_64_after_hwframe+0x44/0xae BUG: memory leak unreferenced object 0xffff88801004cd80 (size 1856): comm "syz-executor641", pid 272, jiffies 4294826057 (age 23.826s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 58 01 00 00 00 00 00 00 ........X....... 01 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............ backtrace: [<00000000dc79ac98>] sk_prot_alloc+0x5f/0x290 net/core/sock.c:1915 [<00000000375ac9c6>] sk_alloc+0x30/0x350 net/core/sock.c:1974 [<000000001b20034f>] unix_create1+0xa3/0x6b0 net/unix/af_unix.c:908 [<00000000103f4e83>] unix_create+0x110/0x220 net/unix/af_unix.c:975 [<000000004b31a0f0>] __sock_create+0x345/0x750 net/socket.c:1468 [<000000006fed8d9f>] sock_create net/socket.c:1519 [inline] [<000000006fed8d9f>] __sys_socketpair+0x1c5/0x570 net/socket.c:1619 [<00000000a926ccf1>] __do_sys_socketpair net/socket.c:1672 [inline] [<00000000a926ccf1>] __se_sys_socketpair net/socket.c:1669 [inline] [<00000000a926ccf1>] __x64_sys_socketpair+0x93/0xf0 net/socket.c:1669 [<0000000053cb0d43>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000053cb0d43>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 [<0000000094dc90c0>] entry_SYSCALL_64_after_hwframe+0x44/0xae BUG: memory leak unreferenced object 0xffff88800d505d40 (size 32): comm "syz-executor641", pid 272, jiffies 4294826057 (age 23.826s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01 00 00 00 01 00 00 00 18 00 00 00 00 00 00 00 ................ backtrace: [<000000002cc568e4>] kmalloc include/linux/slab.h:581 [inline] [<000000002cc568e4>] kzalloc include/linux/slab.h:715 [inline] [<000000002cc568e4>] selinux_sk_alloc_security+0x90/0x200 security/selinux/hooks.c:5245 [<000000005d5bf879>] security_sk_alloc+0x56/0xb0 security/security.c:2255 [<000000001713238c>] sk_prot_alloc+0xa9/0x290 net/core/sock.c:1924 [<00000000375ac9c6>] sk_alloc+0x30/0x350 net/core/sock.c:1974 [<000000001b20034f>] unix_create1+0xa3/0x6b0 net/unix/af_unix.c:908 [<00000000103f4e83>] unix_create+0x110/0x220 net/unix/af_unix.c:975 [<000000004b31a0f0>] __sock_create+0x345/0x750 net/socket.c:1468 [<000000006fed8d9f>] sock_create net/socket.c:1519 [inline] [<000000006fed8d9f>] __sys_socketpair+0x1c5/0x570 net/socket.c:1619 [<00000000a926ccf1>] __do_sys_socketpair net/socket.c:1672 [inline] [<00000000a926ccf1>] __se_sys_socketpair net/socket.c:1669 [inline] [<00000000a926ccf1>] __x64_sys_socketpair+0x93/0xf0 net/socket.c:1669 [<0000000053cb0d43>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000053cb0d43>] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 [<0000000094dc90c0>] entry_SYSCALL_64_after_hwframe+0x44/0xae Syzkaller reproducer: # {Threaded:false Collide:false 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:{Fault:false FaultCall:0 FaultNth:0}} socketpair$unix(0x1, 0x1, 0x0, &(0x7f0000000240)={0xffffffffffffffff, 0xffffffffffffffff}) sendmmsg$inet(r0, &(0x7f0000000940)=[{{0x0, 0x0, &(0x7f00000004c0)=[{&(0x7f0000000040)="586ef8c9df7fe392b02ef89d3bd8307eb335f57c0aec13a0a2e8d1ed00c5cc513ee0e5be5604ce7cd6c43e6292f695141c567d35bdaae29bc6b5489a4b551b447ac64fe9dd540b7b7402d871fb0427bd65f25ad36d870b9442d313bb7db9d88b077b5cea30ab6e3e82ec4fb64a9058a7548cd327857dc624819b1f5d964a3ee139a534fc0fc514e1d4eee397fdc16571d84dd4ad745253cb9256dd10a1b26de9371d45273e7b3e01412797f11d993805a75e8741af49a04aeb0668d1810384a0dadcde3056182d85895d6f4e491a6d2c1c21b890ed72d136cdb03af4989a934b47f4a3055069c06769801f05dcec11489bfebf0e56ff3f513787ce1c99", 0xfd}, {0x0}, {0x0}, {0x0}, {0x0}], 0x5}}, {{0x0, 0x0, 0x0, 0x0, 0x0, 0x258}}], 0x2, 0x8809) sendmsg$unix(r1, &(0x7f0000002780)={0x0, 0x0, &(0x7f0000000000)=[{&(0x7f0000002100)="e2", 0x1}], 0x1}, 0x1) C reproducer: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void sleep_ms(uint64_t ms) { usleep(ms * 1000); } static uint64_t current_time_ms(void) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) exit(1); return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; } static bool write_file(const char* file, const char* what, ...) { char buf[1024]; va_list args; va_start(args, what); vsnprintf(buf, sizeof(buf), what, args); va_end(args); buf[sizeof(buf) - 1] = 0; int len = strlen(buf); int fd = open(file, O_WRONLY | O_CLOEXEC); if (fd == -1) return false; if (write(fd, buf, len) != len) { int err = errno; close(fd); errno = err; return false; } close(fd); return true; } static void kill_and_wait(int pid, int* status) { kill(-pid, SIGKILL); kill(pid, SIGKILL); for (int i = 0; i < 100; i++) { if (waitpid(-1, status, WNOHANG | __WALL) == pid) return; usleep(1000); } DIR* dir = opendir("/sys/fs/fuse/connections"); if (dir) { for (;;) { struct dirent* ent = readdir(dir); if (!ent) break; if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; char abort[300]; snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name); int fd = open(abort, O_WRONLY); if (fd == -1) { continue; } if (write(fd, abort, 1) < 0) { } close(fd); } closedir(dir); } else { } while (waitpid(-1, status, __WALL) != pid) { } } static void setup_test() { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); write_file("/proc/self/oom_score_adj", "1000"); } #define KMEMLEAK_FILE "/sys/kernel/debug/kmemleak" static void setup_leak() { if (!write_file(KMEMLEAK_FILE, "scan")) exit(1); sleep(5); if (!write_file(KMEMLEAK_FILE, "scan")) exit(1); if (!write_file(KMEMLEAK_FILE, "clear")) exit(1); } static void check_leaks(void) { int fd = open(KMEMLEAK_FILE, O_RDWR); if (fd == -1) exit(1); uint64_t start = current_time_ms(); if (write(fd, "scan", 4) != 4) exit(1); sleep(1); while (current_time_ms() - start < 4 * 1000) sleep(1); if (write(fd, "scan", 4) != 4) exit(1); static char buf[128 << 10]; ssize_t n = read(fd, buf, sizeof(buf) - 1); if (n < 0) exit(1); int nleaks = 0; if (n != 0) { sleep(1); if (write(fd, "scan", 4) != 4) exit(1); if (lseek(fd, 0, SEEK_SET) < 0) exit(1); n = read(fd, buf, sizeof(buf) - 1); if (n < 0) exit(1); buf[n] = 0; char* pos = buf; char* end = buf + n; while (pos < end) { char* next = strstr(pos + 1, "unreferenced object"); if (!next) next = end; char prev = *next; *next = 0; fprintf(stderr, "BUG: memory leak\n%s\n", pos); *next = prev; pos = next; nleaks++; } } if (write(fd, "clear", 5) != 5) exit(1); close(fd); if (nleaks) exit(1); } static void execute_one(void); #define WAIT_FLAGS __WALL static void loop(void) { int iter = 0; for (;; iter++) { int pid = fork(); if (pid < 0) exit(1); if (pid == 0) { setup_test(); execute_one(); exit(0); } int status = 0; uint64_t start = current_time_ms(); for (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5000) continue; kill_and_wait(pid, &status); break; } check_leaks(); } } uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; void execute_one(void) { intptr_t res = 0; res = syscall(__NR_socketpair, 1ul, 1ul, 0, 0x20000240ul); if (res != -1) { r[0] = *(uint32_t*)0x20000240; r[1] = *(uint32_t*)0x20000244; } *(uint64_t*)0x20000940 = 0; *(uint32_t*)0x20000948 = 0; *(uint64_t*)0x20000950 = 0x200004c0; *(uint64_t*)0x200004c0 = 0x20000040; memcpy((void*)0x20000040, "\x58\x6e\xf8\xc9\xdf\x7f\xe3\x92\xb0\x2e\xf8\x9d\x3b\xd8\x30\x7e\xb3\x35\xf5\x7c\x0a\xec\x13\xa0\xa2\xe8\xd1\xed\x00\xc5\xcc\x51\x3e\xe0\xe5\xbe\x56\x04\xce\x7c\xd6\xc4\x3e\x62\x92\xf6\x95\x14\x1c\x56\x7d\x35\xbd\xaa\xe2\x9b\xc6\xb5\x48\x9a\x4b\x55\x1b\x44\x7a\xc6\x4f\xe9\xdd\x54\x0b\x7b\x74\x02\xd8\x71\xfb\x04\x27\xbd\x65\xf2\x5a\xd3\x6d\x87\x0b\x94\x42\xd3\x13\xbb\x7d\xb9\xd8\x8b\x07\x7b\x5c\xea\x30\xab\x6e\x3e\x82\xec\x4f\xb6\x4a\x90\x58\xa7\x54\x8c\xd3\x27\x85\x7d\xc6\x24\x81\x9b\x1f\x5d\x96\x4a\x3e\xe1\x39\xa5\x34\xfc\x0f\xc5\x14\xe1\xd4\xee\xe3\x97\xfd\xc1\x65\x71\xd8\x4d\xd4\xad\x74\x52\x53\xcb\x92\x56\xdd\x10\xa1\xb2\x6d\xe9\x37\x1d\x45\x27\x3e\x7b\x3e\x01\x41\x27\x97\xf1\x1d\x99\x38\x05\xa7\x5e\x87\x41\xaf\x49\xa0\x4a\xeb\x06\x68\xd1\x81\x03\x84\xa0\xda\xdc\xde\x30\x56\x18\x2d\x85\x89\x5d\x6f\x4e\x49\x1a\x6d\x2c\x1c\x21\xb8\x90\xed\x72\xd1\x36\xcd\xb0\x3a\xf4\x98\x9a\x93\x4b\x47\xf4\xa3\x05\x50\x69\xc0\x67\x69\x80\x1f\x05\xdc\xec\x11\x48\x9b\xfe\xbf\x0e\x56\xff\x3f\x51\x37\x87\xce\x1c\x99", 253); *(uint64_t*)0x200004c8 = 0xfd; *(uint64_t*)0x200004d0 = 0; *(uint64_t*)0x200004d8 = 0; *(uint64_t*)0x200004e0 = 0; *(uint64_t*)0x200004e8 = 0; *(uint64_t*)0x200004f0 = 0; *(uint64_t*)0x200004f8 = 0; *(uint64_t*)0x20000500 = 0; *(uint64_t*)0x20000508 = 0; *(uint64_t*)0x20000958 = 5; *(uint64_t*)0x20000960 = 0; *(uint64_t*)0x20000968 = 0; *(uint32_t*)0x20000970 = 0; *(uint32_t*)0x20000978 = 0; *(uint64_t*)0x20000980 = 0; *(uint32_t*)0x20000988 = 0; *(uint64_t*)0x20000990 = 0; *(uint64_t*)0x20000998 = 0; *(uint64_t*)0x200009a0 = 0; *(uint64_t*)0x200009a8 = 0x258; *(uint32_t*)0x200009b0 = 0; *(uint32_t*)0x200009b8 = 0; syscall(__NR_sendmmsg, r[0], 0x20000940ul, 2ul, 0x8809ul); *(uint64_t*)0x20002780 = 0; *(uint32_t*)0x20002788 = 0; *(uint64_t*)0x20002790 = 0x20000000; *(uint64_t*)0x20000000 = 0x20002100; memset((void*)0x20002100, 226, 1); *(uint64_t*)0x20000008 = 1; *(uint64_t*)0x20002798 = 1; *(uint64_t*)0x200027a0 = 0; *(uint64_t*)0x200027a8 = 0; *(uint32_t*)0x200027b0 = 0; syscall(__NR_sendmsg, r[1], 0x20002780ul, 1ul); } int main(void) { syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul); syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); setup_leak(); loop(); return 0; }