Subject: Re: Non executable mappings and compatibility options bugs
To: Charles M. Hannum <firstname.lastname@example.org>
From: Chuck Silvers <email@example.com>
Date: 06/28/2004 09:57:18
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