race condition in linux-4.0/tools/net/bpf_jit_disasm.c

From: up201407890
Date: Sat Apr 18 2015 - 09:52:09 EST


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.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/