While testing lang/sbcl, I noticed that something appears to go wrong
when linking a non-PIE executable which references environ. It looks
like the executable ends up with it's own copy of environ, different
from what libc uses.

The following program demonstrates this:

#include <stdio.h>
#include <unistd.h>

extern char **environ;

        char *cmd[] = {"/usr/bin/printenv", "USER", NULL};
        char *fakeenv[] = {"USER=nonexistent", NULL};

        environ = fakeenv;

        execv(cmd[0], cmd);
        return 1;

$ cc -o badenv-pie badenv.c  && ./badenv-pie                                    
$ cc -fno-pie -Wl,-nopie -o badenv-nopie badenv.c && ./badenv-nopie 

It looks like what's happened is the linker has allocated a copy of
environ in the BSS, separate from what libc is using:

$ objdump -t badenv-pie | grep environ                                          
0000000000000000       O *UND*  0000000000000008 environ
$ objdump -t badenv-nopie | grep environ
0000000000601000  w    O .bss   0000000000000008 environ

Reply via email to