Subject: Re: Non executable mappings and compatibility options bugs
To: Chuck Silvers <chuq@chuq.com>
From: Charles M. Hannum <abuse@spamalicious.com>
List: tech-kern
Date: 06/28/2004 19:33:35
On Monday 28 June 2004 16:57, Chuck Silvers wrote:
> On Mon, Jun 21, 2004 at 07:21:37AM +0000, Charles M. Hannum wrote:
> > On Sunday 20 June 2004 13:15, Emmanuel Dreyfus wrote:
> > > Hi
> > >
> > > Wiz reported me a bug in COMPAT_LINUX/powerpc that might be an unwanted
> > > consequence of non executable mappings: Linux's ldconfig will randomly
> > > crash with either SIGSEGV or SIGILL.
> > >
> > > Tracking down the problem with GDB, it occurs always at the same place,
> > > in a function called __DTOR_END__:
> > >
> > > Program received signal SIGILL, Illegal instruction.
> > > 0x1007ff84 in __DTOR_END__ ()
> > > (gdb) x/1i $pc
> > > 0x1007ff84 <__DTOR_END__+4>: blrl
> > >
> > > The instruction is perfectly legal, I assume the problem is just that
> > > the memory is mapped as non executable.
> > >
> > > This function comes from the .dtors ELF section:
> > >
> > > 12 .dtors 00000008 1007ff4c 1007ff4c 0006ff4c 2**2
> > > CONTENTS, ALLOC, LOAD, DATA
> >
> > No, actually, it doesn't occur there. If you add the size and VMA for
> > .dtors, you'll find that the address you're looking at is beyond that.
> > It occurs at the beginning of the GOT, and is standard on PowerPC. The
> > .got section, and the program header that contains it, are marked
> > executable for this reason.
>
> you're right that that address does live in the .got section:
>
> 12 .dtors 00000008 1007ff7c 1007ff7c 0006ff7c 2**2
> CONTENTS, ALLOC, LOAD, DATA
> 13 .got 00000014 1007ff84 1007ff84 0006ff84 2**2
> CONTENTS, ALLOC, LOAD, DATA
>
>
> however, in this binary the .got section is not in an executable
> program header section:
>
> LOAD off 0x00000000 vaddr 0x10000000 paddr 0x10000000 align 2**16
> filesz 0x0006de6c memsz 0x0006de6c flags r-x
> LOAD off 0x0006de70 vaddr 0x1007de70 paddr 0x1007de70 align 2**16
> filesz 0x000022e0 memsz 0x00003604 flags rw-
> NOTE off 0x000000a0 vaddr 0x100000a0 paddr 0x100000a0 align 2**4
> filesz 0x00000020 memsz 0x00000020 flags r--
>
>
> the OEA powerpc MMU hardware only supports execute permissions at the
> granularity of a segment, and since both load sections are in the same
> segment, they are both executable as far as the hardware is concerned.
>
> however, the other thing that the per-page executable permissions are
> used for in this case is to decide whether or not we need to invalidate
> the icache. since the page is not "executable", skip the icache
> invalidation of that page when we map it, so sometimes we trip over some
> stale cache data. we're had this optimization of skipping the icache
> invalidation for a couple years now, so I'm not sure why this problem with
> linux ldconfig only started showing up after the non-executable support was
> added. from what I can tell, the ELF code has always requested the
> permissions specified by the program header, so we should have had the same
> problem before.
I have a dim memory that there is a problem with the GNU linker, that it will
not set the attributes correctly on the GOT section when there is nothing
else in it -- i.e. when linking with -Bsymbolic, and that this used to be
worked around in the single case where we use -Bsymbolic, in ld.elf_so, with
an explicit cache flush there. This is no longer the case, though, and I
removed the cache flush some last year.