Messages in this thread | | | Date | Sat, 18 Apr 2015 15:19:03 +0200 | From | up201407890@alunos ... | Subject | race condition in linux-4.0/tools/net/bpf_jit_disasm.c |
| |
Hi,
There's a race condition in the linux-4.0 kernel at tools/net/bpf_jit_disasm.c caused /proc/self/exe
linux-4.0/tools/net/bpf_jit_disasm.c
static void get_exec_path(char *tpath, size_t size) { char *path; ssize_t len;
snprintf(tpath, size, "/proc/%d/exe", (int) getpid()); tpath[size - 1] = 0;
path = strdup(tpath); assert(path);
len = readlink(path, tpath, size); tpath[len] = 0;
free(path); }
static void get_asm_insns(uint8_t *image, size_t len, int opcodes) {
[...]
bfd *bfdf;
memset(tpath, 0, sizeof(tpath)); get_exec_path(tpath, sizeof(tpath));
bfdf = bfd_openr(tpath, NULL);
[...]
disassemble = disassembler(bfdf); assert(disassemble);
do { printf("%4x:\t", pc);
count = disassemble(pc, &info);
if (opcodes) { printf("\n\t"); for (i = 0; i < count; ++i) printf("%02x ", (uint8_t) image[pc + i]); } printf("\n");
pc += count; } while(count > 0 && pc < len);
bfd_close(bfdf); }
The problem with this is that get_exec_path trusts the /proc/self/exe symlink, even though it is possible to link it anywhere you want.
$ cd /tmp $ ls -la /proc/self/exe lrwxrwxrwx 1 saken saken 0 Apr 17 23:24 /proc/self/exe -> /bin/ls $ ln `which ls` ls $ ./ls -la /proc/self/exe lrwxrwxrwx 1 saken saken 0 Apr 17 23:24 /proc/self/exe -> /tmp/ls
The race is won if one can replace the current file after snprintf(tpath, size, "/proc/%d/exe", (int) getpid()); and before bfd_openr(tpath, NULL); making it point to another file and open it. At this point, it will disassemble the wrong file and not itself
---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.
| |