Created attachment 164311 [details] small program that allow to reproduce the problem When a tracer try to access a tracee stack area not yet mapped and that is above tracer stack size limit, we got an error. You can reproduce the problem with the attach program - Compile it > gcc -g exec.c - Setup limit on tracer stack size > ulimit -Ss 8192 - Run compile program under gdb > gdb a./out - Now under gdb prompt (gdb) b exec_here Breakpoint 1 at 0x400632: file exec.c, line 8. (gdb) r Starting program: /home/mike/rootfs/proot_stack_pb/a.out SP = 0x00007fffffffe1c0 try print *0x00007fffff5fe1b0 Breakpoint 1, exec_here (cmd=0x7fffff6fe1b0 "ls") at exec.c:8 8 fprintf(stderr, "SP = 0x%016lx\n", alloca(0)); (gdb) print *0x00007fffff5fe1b0 Cannot access memory at address 0x7fffff5fe1b0 If you try the same sequence but replace 'ulimit -Ss 8192' by 'ulimit -Ss 16384' it will work fine which is the correct behaviour. Problem is due to acct_stack_growth() from mm/mmap.c file. There is a check that fail since it use tracer stack size limit instead of the tracee stack size limit. static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, unsigned long grow) { 2100 struct mm_struct *mm = vma->vm_mm; 2101 struct rlimit *rlim = current->signal->rlim; ... 2108 /* Stack limit test */ 2109 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) 2110 return -ENOMEM; Line 2101 we use current process limits which is the tracer process limits.
(In reply to mike from comment #0) > > static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, > unsigned long grow) > { > 2100 struct mm_struct *mm = vma->vm_mm; > 2101 struct rlimit *rlim = current->signal->rlim; > ... > 2108 /* Stack limit test */ > 2109 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) > 2110 return -ENOMEM; > > Line 2101 we use current process limits which is the tracer process limits. Yes, and the same function also checks the caller's RLIMIT_AS/MEMLOCK. I do not see a simple fix, and in fact I am not sure we really want to fix this oddity, although I agree that this doesn't look very good. Unlikely we want to complicate the get_user_pages() paths... Perhaps we could add task_struct->active_rlim[] and change task_rlimit(), but this doesn't look good too, imo. And this is not ptrace-specific. Say, /proc/pid/mem. This case is even worse, the task can already go away when mem_rw() is called so this path can't even know which rlimits it should check. We have mm->owner which we could probably use if current->mm != mm, but it depends on CONFIG_MEMCG. And personally I think it should die, so it should not have the new users, imho. In short, I'd vote for "won't fix".