Bug 11063
Summary: | lack of GNU_STACK header doesn't result in rwx stack on i386 | ||
---|---|---|---|
Product: | Memory Management | Reporter: | PaX Team (pageexec) |
Component: | Other | Assignee: | Andrew Morton (akpm) |
Status: | CLOSED CODE_FIX | ||
Severity: | normal | CC: | bunk |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | Subsystem: | ||
Regression: | --- | Bisected commit-id: |
Description
PaX Team
2008-07-09 12:13:05 UTC
Reply-To: akpm@linux-foundation.org (switched to email. Please respond via emailed reply-to-all, not via the bugzilla web interface). On Wed, 9 Jul 2008 12:13:05 -0700 (PDT) bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=11063 > > Summary: lack of GNU_STACK header doesn't result in rwx stack on > i386 > Product: Memory Management > Version: 2.5 > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: normal > Priority: P1 > Component: Other > AssignedTo: akpm@osdl.org > ReportedBy: pageexec@freemail.hu > > > Latest working kernel version: unknown, probably before the introduction of > unlimited argv > Earliest failing kernel version: unknown, probably after the introduction of > unlimited argv, 2.6.26-rc9 definitely fails > Distribution: > Hardware Environment: > Software Environment: > Problem Description: > ELF/i386 traditionally has an executable stack which in the PT_GNU_STACK > world > is provided two ways: if the ELF has a RWE PT_GNU_STACK program header or if > it > lacks that program header. due to this regression, the latter case results in > a > non-executable stack with corresponding breakage of (old) userland binaries > that use nested function trampolines. > > this bug was probably introduced when the unlimited argv feature was merged: > in > that system the stack vma (and its vm_flags) is initialized too early, before > the incoming process' ELF header is consulted, which on i386 means that the > personality used for determining the executable status of the stack is that > of > the old process, not the incoming one. later, in setup_arg_pages, only the > explicit setting (disable/enable) of stack executability is honoured, > EXSTACK_DEFAULT isn't consulted (i guess the assumption was that the initial > ->vm_flags setting got it right). > > Steps to reproduce: run any ELF that lacks a PT_GNU_STACK program header and > check its stack vma, it'll be rw-, instead of rwx. > Reply-To: akpm@linux-foundation.org err, I missed the mailing list cc. Let me resend. On Wed, 9 Jul 2008 15:27:16 -0700 Andrew Morton <akpm@linux-foundation.org> wrote: > > (switched to email. Please respond via emailed reply-to-all, not via the > bugzilla web interface). > > On Wed, 9 Jul 2008 12:13:05 -0700 (PDT) bugme-daemon@bugzilla.kernel.org > wrote: > > > http://bugzilla.kernel.org/show_bug.cgi?id=11063 > > > > Summary: lack of GNU_STACK header doesn't result in rwx stack on > > i386 > > Product: Memory Management > > Version: 2.5 > > Platform: All > > OS/Version: Linux > > Tree: Mainline > > Status: NEW > > Severity: normal > > Priority: P1 > > Component: Other > > AssignedTo: akpm@osdl.org > > ReportedBy: pageexec@freemail.hu > > > > > > Latest working kernel version: unknown, probably before the introduction of > > unlimited argv > > Earliest failing kernel version: unknown, probably after the introduction > of > > unlimited argv, 2.6.26-rc9 definitely fails > > Distribution: > > Hardware Environment: > > Software Environment: > > Problem Description: > > ELF/i386 traditionally has an executable stack which in the PT_GNU_STACK > world > > is provided two ways: if the ELF has a RWE PT_GNU_STACK program header or > if it > > lacks that program header. due to this regression, the latter case results > in a > > non-executable stack with corresponding breakage of (old) userland binaries > > that use nested function trampolines. > > > > this bug was probably introduced when the unlimited argv feature was > merged: in > > that system the stack vma (and its vm_flags) is initialized too early, > before > > the incoming process' ELF header is consulted, which on i386 means that the > > personality used for determining the executable status of the stack is that > of > > the old process, not the incoming one. later, in setup_arg_pages, only the > > explicit setting (disable/enable) of stack executability is honoured, > > EXSTACK_DEFAULT isn't consulted (i guess the assumption was that the > initial > > ->vm_flags setting got it right). > > > > Steps to reproduce: run any ELF that lacks a PT_GNU_STACK program header > and > > check its stack vma, it'll be rw-, instead of rwx. > > > Reply-To: akpm@linux-foundation.org (switched to email. Please respond via emailed reply-to-all, not via the bugzilla web interface). On Wed, 9 Jul 2008 12:13:05 -0700 (PDT) bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=11063 > > Summary: lack of GNU_STACK header doesn't result in rwx stack on > i386 > Product: Memory Management > Version: 2.5 > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: normal > Priority: P1 > Component: Other > AssignedTo: akpm@osdl.org > ReportedBy: pageexec@freemail.hu > > > Latest working kernel version: unknown, probably before the introduction of > unlimited argv > Earliest failing kernel version: unknown, probably after the introduction of > unlimited argv, 2.6.26-rc9 definitely fails > Distribution: > Hardware Environment: > Software Environment: > Problem Description: > ELF/i386 traditionally has an executable stack which in the PT_GNU_STACK > world > is provided two ways: if the ELF has a RWE PT_GNU_STACK program header or if > it > lacks that program header. due to this regression, the latter case results in > a > non-executable stack with corresponding breakage of (old) userland binaries > that use nested function trampolines. > > this bug was probably introduced when the unlimited argv feature was merged: > in > that system the stack vma (and its vm_flags) is initialized too early, before > the incoming process' ELF header is consulted, which on i386 means that the > personality used for determining the executable status of the stack is that > of > the old process, not the incoming one. later, in setup_arg_pages, only the > explicit setting (disable/enable) of stack executability is honoured, > EXSTACK_DEFAULT isn't consulted (i guess the assumption was that the initial > ->vm_flags setting got it right). > > Steps to reproduce: run any ELF that lacks a PT_GNU_STACK program header and > check its stack vma, it'll be rw-, instead of rwx. > Kernel Bugzilla #11063 points out that on some architectures (e.g. x86_32) exec'ing an ELF without a PT_GNU_STACK program header should default to an executable stack; but this got broken by the unlimited argv feature because stack vma is now created before the right personality has been established: so breaking old binaries using nested function trampolines. Therefore re-evaluate VM_STACK_FLAGS in setup_arg_pages, where stack vm_flags used to be set, before the mprotect_fixup. Checking through our existing VM_flags, none would have changed since insert_vm_struct: so this seems safer than finding a way through the personality labyrinth. Reported-by: pageexec@freemail.hu Signed-off-by: Hugh Dickins <hugh@veritas.com> Cc: stable@kernel.org --- fs/exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- 2.6.26-rc9/fs/exec.c 2008-06-21 08:41:19.000000000 +0100 +++ linux/fs/exec.c 2008-07-10 20:02:25.000000000 +0100 @@ -610,7 +610,7 @@ int setup_arg_pages(struct linux_binprm bprm->exec -= stack_shift; down_write(&mm->mmap_sem); - vm_flags = vma->vm_flags; + vm_flags = VM_STACK_FLAGS; /* * Adjust stack execute permissions; explicitly enable for fixed by commit 96a8e13ed44e380fc2bb6c711d74d5ba698c00b2 On 10 Jul 2008 at 21:19, Hugh Dickins wrote: > Kernel Bugzilla #11063 points out that on some architectures (e.g. x86_32) > exec'ing an ELF without a PT_GNU_STACK program header should default to an > executable stack; but this got broken by the unlimited argv feature because > stack vma is now created before the right personality has been established: > so breaking old binaries using nested function trampolines. > > Therefore re-evaluate VM_STACK_FLAGS in setup_arg_pages, where stack > vm_flags used to be set, before the mprotect_fixup. Checking through > our existing VM_flags, none would have changed since insert_vm_struct: > so this seems safer than finding a way through the personality labyrinth. alternatively, if there's a concern of stack_vma->vm_flags manipulation during execve (maybe not now, but in the future or in non-ELF formats that also want to rely on personality bits), you could opt for a safer vm_flags = vma->vm_flags | (VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC)); to just recompute the exec rights related bits. > Reported-by: pageexec@freemail.hu > Signed-off-by: Hugh Dickins <hugh@veritas.com> > Cc: stable@kernel.org > --- > > fs/exec.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > --- 2.6.26-rc9/fs/exec.c 2008-06-21 08:41:19.000000000 +0100 > +++ linux/fs/exec.c 2008-07-10 20:02:25.000000000 +0100 > @@ -610,7 +610,7 @@ int setup_arg_pages(struct linux_binprm > bprm->exec -= stack_shift; > > down_write(&mm->mmap_sem); > - vm_flags = vma->vm_flags; > + vm_flags = VM_STACK_FLAGS; > > /* > * Adjust stack execute permissions; explicitly enable for > On Thu, 10 Jul 2008, pageexec@freemail.hu wrote: > On 10 Jul 2008 at 21:19, Hugh Dickins wrote: > > > Therefore re-evaluate VM_STACK_FLAGS in setup_arg_pages, where stack > > vm_flags used to be set, before the mprotect_fixup. Checking through > > our existing VM_flags, none would have changed since insert_vm_struct: > > so this seems safer than finding a way through the personality labyrinth. > > alternatively, if there's a concern of stack_vma->vm_flags manipulation > during execve (maybe not now, but in the future or in non-ELF formats > that also want to rely on personality bits), you could opt for a safer > > vm_flags = vma->vm_flags | (VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC)); > > to just recompute the exec rights related bits. True. It was a concern that crossed my mind (I was thinking particularly of the VM_ACCOUNT flag, which gets added in once we deal with a writable private mapping, but is set from the start here anyway), but I don't think it's worth changing my > > - vm_flags = vma->vm_flags; > > + vm_flags = VM_STACK_FLAGS; now that's already there in Linus' tree. If a VM_flag gets added that changes the picture, it might even need your line above to be changed. Hugh |