lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20150418151903.37227dxxv4qs6j48@webmail.alunos.dcc.fc.up.pt>
Date:	Sat, 18 Apr 2015 15:19:03 +0200
From:	up201407890@...nos.dcc.fc.up.pt
To:	linux-kernel@...r.kernel.org
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.

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ