Wrong linkage to environ with -Wl,-nopie

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Wrong linkage to environ with -Wl,-nopie

Josh Elsasser
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;

int
main()
{
        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                                                
nonexistent
$ cc -fno-pie -Wl,-nopie -o badenv-nopie badenv.c && ./badenv-nopie
joshe


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 | Threaded
Open this post in threaded view
|

Re: Wrong linkage to environ with -Wl,-nopie

Josh Elsasser
This problem still seems to be present. Anyone interested?

On Wed, Mar 07, 2018 at 01:40:37PM -0800, Josh Elsasser wrote:

> 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;
>
> int
> main()
> {
> 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                                                
> nonexistent
> $ cc -fno-pie -Wl,-nopie -o badenv-nopie badenv.c && ./badenv-nopie
> joshe
>
>
> 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 | Threaded
Open this post in threaded view
|

Re: Wrong linkage to environ with -Wl,-nopie

Mark Kettenis
> Date: Fri, 27 Apr 2018 21:32:19 -0700
> From: Josh Elsasser <[hidden email]>
>
> This problem still seems to be present. Anyone interested?

It's a bug in our binutils that is hard to fix.

Short-term fix would be to remove the -fno-pie flag,  Long term fix is
to switch to lld.  Unfortunately lld has a different issue that
prevents linking the example coe you provided.

> On Wed, Mar 07, 2018 at 01:40:37PM -0800, Josh Elsasser wrote:
> > 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;
> >
> > int
> > main()
> > {
> > 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                                                
> > nonexistent
> > $ cc -fno-pie -Wl,-nopie -o badenv-nopie badenv.c && ./badenv-nopie
> > joshe
> >
> >
> > 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 | Threaded
Open this post in threaded view
|

Re: Wrong linkage to environ with -Wl,-nopie

Josh Elsasser
On Sun, Apr 29, 2018 at 01:28:32AM +0200, Mark Kettenis wrote:

> > Date: Fri, 27 Apr 2018 21:32:19 -0700
> > From: Josh Elsasser <[hidden email]>
> >
> > This problem still seems to be present. Anyone interested?
>
> It's a bug in our binutils that is hard to fix.
>
> Short-term fix would be to remove the -fno-pie flag,  Long term fix is
> to switch to lld.  Unfortunately lld has a different issue that
> prevents linking the example coe you provided.

All right, thanks. I believe the code can be made to run as PIE fairly
easily.