Messages in this thread | | | Subject | Re: [PATCH v2] x86/mm/fault: Allow stack access below %rsp | From | Waiman Long <> | Date | Tue, 6 Nov 2018 15:14:15 -0500 |
| |
On 11/06/2018 03:12 PM, Waiman Long wrote: > The current x86 page fault handler allows stack access below the stack > pointer if it is no more than 64k+256 bytes. Any access beyond the 64k+ > limit will cause a segmentation fault. > > The gcc -fstack-check option generates code to probe the stack for > large stack allocation to see if the stack is accessible. The newer gcc > does that while updating the %rsp simultaneously. Older gcc's like gcc4 > doesn't do that. As a result, an application compiled with an old gcc > and the -fstack-check option may fail to start at all. > > % cat test.c > int main() { > char tmp[1024*128]; > printf("### ok\n"); > return 0; > } > % gcc -fstack-check -g -o test test.c > % ./test > Segmentation fault > > The old binary was working in older kernels where expand_stack() was > somehow called before the check. But it is not working in newer kernels. > Besides, the 64k+ limit check is kind of crude and will not catch a > lot of mistakes that userspace applications may be misbehaving anyway. > I think the kernel isn't the right place for this kind of tests. We > should leave it to userspace instrumentation tools to perform them. > > The 64k+ limit check is now removed to just let expand_stack() decide > if a segmentation fault should happen, when the RLIMIT_STACK limit is > exceeded, for example. > > Signed-off-by: Waiman Long <longman@redhat.com> > --- > arch/x86/mm/fault.c | 12 ------------ > 1 file changed, 12 deletions(-) > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index 71d4b9d..29525cf 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -1380,18 +1380,6 @@ void do_user_addr_fault(struct pt_regs *regs, > bad_area(regs, sw_error_code, address); > return; > } > - if (sw_error_code & X86_PF_USER) { > - /* > - * Accessing the stack below %sp is always a bug. > - * The large cushion allows instructions like enter > - * and pusha to work. ("enter $65535, $31" pushes > - * 32 pointers and then decrements %sp by 65535.) > - */ > - if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) { > - bad_area(regs, sw_error_code, address); > - return; > - } > - } > if (unlikely(expand_stack(vma, address))) { > bad_area(regs, sw_error_code, address); > return;
This v2 patch has no code change. I just updated the commit log to capture some of the conversion that I had with the reviewers.
Cheers, Longman
| |