ppc64 sbrk returns executable heap in 32-bit emulation mode
Florian Weimer
fweimer at redhat.com
Mon May 16 18:51:38 AEST 2016
On 05/16/2016 08:24 AM, Alan Modra wrote:
> On Thu, May 12, 2016 at 03:41:09PM +0200, Florian Weimer wrote:
>> We noticed that on ppc64, the sbrk system call in the 32-bit subsystem
>> returns executable memory. I assume it is related to this, in
>> arch/powerpc/include/asm/page.h:
>>
>> /*
>> * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
>> * and needs to be executable. This means the whole heap ends
>> * up being executable.
>> */
>> #define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
>> VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
>>
>>
>> What is the rationale for this? This comment must be *really* old,
>
> I think the comment is just plain wrong. ppc32 needs an executable
> stack because it builds trampolines on the stack to support calling
> nested functions. I presume that's why the heap is executable. (If
> I'm wrong about heap+stack needing the same protection then I can't
> think of any reason to require an executable heap.)
But the stack is *not* executable. The program is marked correctly with
GNU_STACK:
GNU_STACK 0x000000 0x00000000 0x00000000 0x000000 0x000000 RW 0x10
If this program header were not there (or said RWX instead of RW), then
I expect the kernel would make the stack executable, for backwards
compatibility.
And the test reports this:
# Subtests with executable mappings or inconsistent results
exec MAP_ANONYMOUS with R|W, then mprotect R|X
exec MAP_ANONYMOUS with R|X, then mprotect R|W, mprotect R|X
FAIL exec malloc (small) (unexpected result)
FAIL exec malloc (page size) (unexpected result)
exec MAP_ANONYMOUS, with PROT_EXEC, without mprotect
exec file with MAP_PRIVATE, with PROT_EXEC, without mprotect,
without alias
exec file with MAP_SHARED, with PROT_EXEC, without mprotect,
without alias
exec shared memory with MAP_PRIVATE, with PROT_EXEC, without
mprotect, without alias
exec shared memory with MAP_SHARED, with PROT_EXEC, without
mprotect, without alias
exec file with MAP_SHARED, with PROT_EXEC, without mprotect,
with alias
exec shared memory with MAP_SHARED, with PROT_EXEC, without
mprotect, with alias
exec MAP_ANONYMOUS, with PROT_EXEC, with mprotect
exec file with MAP_PRIVATE, with PROT_EXEC, with mprotect,
without alias
exec file with MAP_SHARED, with PROT_EXEC, with mprotect,
without alias
exec shared memory with MAP_PRIVATE, with PROT_EXEC, with
mprotect, without alias
exec shared memory with MAP_SHARED, with PROT_EXEC, with
mprotect, without alias
exec file with MAP_SHARED, with PROT_EXEC, with mprotect, with
alias
exec shared memory with MAP_SHARED, with PROT_EXEC, with
mprotect, with alias
(Sorry for the line wrapping, also available at
<https://paste.fedoraproject.org/367036/>.)
The tests I'm using are these: <https://pagure.io/execmod-tests> It
also covers the stack, but it is not listed in the summary because it is
not executable.
Only the heap is executable. Everything else is set up as expected by
the kernel or by glibc.
Florian
More information about the Linuxppc-dev
mailing list