Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-11 Thread Helge Deller

On 02/10/2010 06:31 AM, Michael Neuling wrote:

In message20100210141016.4d18.a69d9...@jp.fujitsu.com  you wrote:

On 02/09/2010 10:51 PM, Michael Neuling wrote:

I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
as well.


There's only one CONFIG_GROWSUP arch - parisc.
Could someone please test it on parisc?


I did.


How about doing:
'ulimit -s 15; ls'
before and after the patch is applied.  Before it's applied, 'ls' should
be killed.  After the patch is applied, 'ls' should no longer be killed.

I'm suggesting a stack limit of 15KB since it's small enough to trigger
20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
case to handle correctly with this code.

4K pages on parisc should be fine to test with.


Mikey, thanks for the suggested test plan.

I'm not sure if your patch does it correct for parisc/stack-grows-up-case.

I tested your patch on  a 4k pages kernel:
r...@c3000:~# uname -a
Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Li

nux


Without your patch:
r...@c3000:~# ulimit -s 15; ls
Killed
-  correct.

With your patch:
r...@c3000:~# ulimit -s 15; ls
Killed
_or_:
r...@c3000:~# ulimit -s 15; ls
Segmentation fault
-  ??

Any idea?


My x86_64 box also makes segmentation fault. I think ulimit -s 15 is too sm

all stack for ls.

ulimit -s 27; ls   wroks perfectly fine.


Arrh.  I asked Helge offline earlier to check what use to work on parisc
on 2.6.31.

I guess PPC has a nice clean non-bloated ABI :-D


Hi Mikey,

I tested again, and it works for me with ulimit -s 27 as well (on a 4k, 32bit 
kernel).
Still, I'm not 100%  sure if your patch is correct.
Anyway, it seems to work.

But what makes me wonder is, why EXTRA_STACK_VM_PAGES is defined in pages at 
all.
You wrote in your patch description:

This bug means that when limiting the stack to less the 20*PAGE_SIZE (eg.
80K on 4K pages or 'ulimit -s 79') all processes will be killed before
they start.  This is particularly bad with 64K pages, where a ulimit below
1280K will kill every process.


Wouldn't it make sense to define and use EXTRA_STACK_VM_SIZE instead (e.g. as 
20*4096 = 80k)?
This extra stack reservation should IMHO be independend of the actual kernel 
page size.

Helge
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-11 Thread Michael Neuling
In message 4b7481a6.7080...@gmx.de you wrote:
 On 02/10/2010 06:31 AM, Michael Neuling wrote:
  In message20100210141016.4d18.a69d9...@jp.fujitsu.com  you wrote:
  On 02/09/2010 10:51 PM, Michael Neuling wrote:
  I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
  as well.
 
  There's only one CONFIG_GROWSUP arch - parisc.
  Could someone please test it on parisc?
 
  I did.
 
  How about doing:
  'ulimit -s 15; ls'
  before and after the patch is applied.  Before it's applied, 'ls' should
  be killed.  After the patch is applied, 'ls' should no longer be killed.
 
  I'm suggesting a stack limit of 15KB since it's small enough to trigger
  20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickie
r
  case to handle correctly with this code.
 
  4K pages on parisc should be fine to test with.
 
  Mikey, thanks for the suggested test plan.
 
  I'm not sure if your patch does it correct for parisc/stack-grows-up-case
.
 
  I tested your patch on  a 4k pages kernel:
  r...@c3000:~# uname -a
  Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/
Li
  nux
 
  Without your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  -  correct.
 
  With your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  _or_:
  r...@c3000:~# ulimit -s 15; ls
  Segmentation fault
  -  ??
 
  Any idea?
 
  My x86_64 box also makes segmentation fault. I think ulimit -s 15 is too
 sm
  all stack for ls.
  ulimit -s 27; ls   wroks perfectly fine.
 
  Arrh.  I asked Helge offline earlier to check what use to work on parisc
  on 2.6.31.
 
  I guess PPC has a nice clean non-bloated ABI :-D
 
 Hi Mikey,
 
 I tested again, and it works for me with ulimit -s 27 as well (on a
 4k, 32bit kernel).
 Still, I'm not 100%  sure if your patch is correct.

Thanks for retesting

Did ulimit -s 27 fail before you applied?

 Anyway, it seems to work.
 
 But what makes me wonder is, why EXTRA_STACK_VM_PAGES is defined in pages at 
all.
 You wrote in your patch description:
  This bug means that when limiting the stack to less the 20*PAGE_SIZE (eg.
  80K on 4K pages or 'ulimit -s 79') all processes will be killed before
  they start.  This is particularly bad with 64K pages, where a ulimit below
  1280K will kill every process.
 
 Wouldn't it make sense to define and use EXTRA_STACK_VM_SIZE instead
 (e.g. as 20*4096 = 80k)?  This extra stack reservation should IMHO be
 independend of the actual kernel page size.

If you look back through this thread, that has already been noted but
it's a separate issue to this bug, so that change will be deferred till
2.6.34.

Mikey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Michael Neuling
In message 20100209154141.03f0.a69d9...@jp.fujitsu.com you wrote:
  When reserving stack space for a new process, make sure we're not
  attempting to expand the stack by more than rlimit allows.
  
  This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba mm:
  variable length argument support and unmasked by
  fc63cf237078c86214abcb2ee9926d8ad289da9b exec: setup_arg_pages() fails
  to return errors.  This bug means when limiting the stack to less the
  20*PAGE_SIZE (eg. 80K on 4K pages or 'ulimit -s 79') all processes will
  be killed before they start.  This is particularly bad with 64K pages,
  where a ulimit below 1280K will kill every process.
  
  Signed-off-by: Michael Neuling mi...@neuling.org
  Cc: sta...@kernel.org
  ---
  Attempts to answer comments from Kosaki Motohiro.
  
  Tested on PPC only, hence !CONFIG_STACK_GROWSUP.  Someone should
  probably ACK for an arch with CONFIG_STACK_GROWSUP.
  
  As noted, stable needs the same patch, but 2.6.32 doesn't have the
  rlimit() helper.
  
   fs/exec.c |   21 ++---
   1 file changed, 18 insertions(+), 3 deletions(-)
  
  Index: linux-2.6-ozlabs/fs/exec.c
  ===
  --- linux-2.6-ozlabs.orig/fs/exec.c
  +++ linux-2.6-ozlabs/fs/exec.c
  @@ -555,6 +555,7 @@ static int shift_arg_pages(struct vm_are
   }
   
   #define EXTRA_STACK_VM_PAGES   20  /* random */
  +#define ALIGN_DOWN(addr,size)  ((addr)(~((size)-1)))
   
   /*
* Finalizes the stack vm_area_struct. The flags and permissions are updat
ed,
  @@ -570,7 +571,7 @@ int setup_arg_pages(struct linux_binprm 
  struct vm_area_struct *vma = bprm-vma;
  struct vm_area_struct *prev = NULL;
  unsigned long vm_flags;
  -   unsigned long stack_base;
  +   unsigned long stack_base, stack_expand, stack_expand_lim, stack_size;
   
   #ifdef CONFIG_STACK_GROWSUP
  /* Limit stack size to 1GB */
  @@ -627,10 +628,24 @@ int setup_arg_pages(struct linux_binprm 
  goto out_unlock;
  }
   
  +   stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
  +   stack_size = vma-vm_end - vma-vm_start;
  +   if (rlimit(RLIMIT_STACK)  stack_size)
  +   stack_expand_lim = 0; /* don't shrick the stack */
  +   else
  +   /*
  +* Align this down to a page boundary as expand_stack
  +* will align it up.
  +*/
  +   stack_expand_lim = ALIGN_DOWN(rlimit(RLIMIT_STACK) - stack_size
,
  + PAGE_SIZE);
  +   /* Initial stack must not cause stack overflow. */
  +   if (stack_expand  stack_expand_lim)
  +   stack_expand = stack_expand_lim;
   #ifdef CONFIG_STACK_GROWSUP
  -   stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
  +   stack_base = vma-vm_end + stack_expand;
   #else
  -   stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
  +   stack_base = vma-vm_start - stack_expand;
   #endif
  ret = expand_stack(vma, stack_base);
  if (ret)
 
 Umm.. It looks correct. but the nested complex if statement seems a bit ugly.
 Instead, How about following?

I don't like the duplicated code in the #ifdef/else but I can live with it.

 note: it's untested.

Works for me on ppc64 with 4k and 64k pages.  Thanks!

I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
as well.

Mikey

 
 
 
 ===
 From: Michael Neuling mi...@neuling.org
 Subject: Restrict initial stack space expansion to rlimit
 
 When reserving stack space for a new process, make sure we're not
 attempting to expand the stack by more than rlimit allows.
 
 This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba mm:
 variable length argument support and unmasked by
 fc63cf237078c86214abcb2ee9926d8ad289da9b exec: setup_arg_pages() fails
 to return errors.  This bug means when limiting the stack to less the
 20*PAGE_SIZE (eg. 80K on 4K pages or 'ulimit -s 79') all processes will
 be killed before they start.  This is particularly bad with 64K pages,
 where a ulimit below 1280K will kill every process.
 
 [kosaki.motoh...@jp.fujitsu.com: cleanups]
 Signed-off-by: Michael Neuling mi...@neuling.org
 Signed-off-by: KOSAKI Motohiro kosaki.motoh...@jp.fujitsu.com
 Cc: sta...@kernel.org
 ---
 Attempts to answer comments from Kosaki Motohiro.
 
 Tested on PPC only, hence !CONFIG_STACK_GROWSUP.  Someone should
 probably ACK for an arch with CONFIG_STACK_GROWSUP.
 
 As noted, stable needs the same patch, but 2.6.32 doesn't have the
 rlimit() helper.
 
 diff --git a/fs/exec.c b/fs/exec.c
 index 6f7fb0c..325bad4 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -573,6 +573,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
   struct vm_area_struct *prev = NULL;
   unsigned long vm_flags;
   unsigned long stack_base;
 + unsigned long stack_size;
 + unsigned long stack_expand;
 + unsigned long rlim_stack;
  
  #ifdef CONFIG_STACK_GROWSUP
   /* Limit stack size to 1GB 

Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Andrew Morton
On Tue, 09 Feb 2010 19:59:27 +1100
Michael Neuling mi...@neuling.org wrote:

   + /* Initial stack must not cause stack overflow. */
   + if (stack_expand  stack_expand_lim)
   + stack_expand = stack_expand_lim;
#ifdef CONFIG_STACK_GROWSUP
   - stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
   + stack_base = vma-vm_end + stack_expand;
#else
   - stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
   + stack_base = vma-vm_start - stack_expand;
#endif
 ret = expand_stack(vma, stack_base);
 if (ret)
  
  Umm.. It looks correct. but the nested complex if statement seems a bit 
  ugly.
  Instead, How about following?
 
 I don't like the duplicated code in the #ifdef/else but I can live with it.

cleanup the cleanup:

--- 
a/fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit-cleanup-cleanup
+++ a/fs/exec.c
@@ -637,20 +637,17 @@ int setup_arg_pages(struct linux_binprm 
 * will align it up.
 */
rlim_stack = rlimit(RLIMIT_STACK)  PAGE_MASK;
-   if (rlim_stack  stack_size)
-   rlim_stack = stack_size;
+   rlim_stack = min(rlim_stack, stack_size);
 #ifdef CONFIG_STACK_GROWSUP
-   if (stack_size + stack_expand  rlim_stack) {
+   if (stack_size + stack_expand  rlim_stack)
stack_base = vma-vm_start + rlim_stack;
-   } else {
+   else
stack_base = vma-vm_end + stack_expand;
-   }
 #else
-   if (stack_size + stack_expand  rlim_stack) {
+   if (stack_size + stack_expand  rlim_stack)
stack_base = vma-vm_end - rlim_stack;
-   } else {
+   else
stack_base = vma-vm_start - stack_expand;
-   }
 #endif
ret = expand_stack(vma, stack_base);
if (ret)
_

  note: it's untested.
 
 Works for me on ppc64 with 4k and 64k pages.  Thanks!
 
 I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
 as well.

There's only one CONFIG_GROWSUP arch - parisc.

Guys, here's the rolled-up patch.  Could someone please test it on
parisc?

err, I'm not sure what one needs to do to test it, actually. 
Presumably it involves setting an unusual `ulimit -s'.  Can someone
please suggest a test plan?




From: Michael Neuling mi...@neuling.org

When reserving stack space for a new process, make sure we're not
attempting to expand the stack by more than rlimit allows.

This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba (mm:
variable length argument support) and unmasked by
fc63cf237078c86214abcb2ee9926d8ad289da9b (exec: setup_arg_pages() fails
to return errors).

This bug means that when limiting the stack to less the 20*PAGE_SIZE (eg. 
80K on 4K pages or 'ulimit -s 79') all processes will be killed before
they start.  This is particularly bad with 64K pages, where a ulimit below
1280K will kill every process.

Signed-off-by: Michael Neuling mi...@neuling.org
Cc: KOSAKI Motohiro kosaki.motoh...@jp.fujitsu.com
Cc: Americo Wang xiyou.wangc...@gmail.com
Cc: Anton Blanchard an...@samba.org
Cc: Oleg Nesterov o...@redhat.com
Cc: James Morris jmor...@namei.org
Cc: Ingo Molnar mi...@elte.hu
Cc: Serge Hallyn se...@us.ibm.com
Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
Cc: sta...@kernel.org

 fs/exec.c |   21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff -puN fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit 
fs/exec.c
--- a/fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit
+++ a/fs/exec.c
@@ -571,6 +571,9 @@ int setup_arg_pages(struct linux_binprm 
struct vm_area_struct *prev = NULL;
unsigned long vm_flags;
unsigned long stack_base;
+   unsigned long stack_size;
+   unsigned long stack_expand;
+   unsigned long rlim_stack;
 
 #ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
@@ -627,10 +630,24 @@ int setup_arg_pages(struct linux_binprm 
goto out_unlock;
}
 
+   stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_size = vma-vm_end - vma-vm_start;
+   /*
+* Align this down to a page boundary as expand_stack
+* will align it up.
+*/
+   rlim_stack = rlimit(RLIMIT_STACK)  PAGE_MASK;
+   rlim_stack = min(rlim_stack, stack_size);
 #ifdef CONFIG_STACK_GROWSUP
-   stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   if (stack_size + stack_expand  rlim_stack)
+   stack_base = vma-vm_start + rlim_stack;
+   else
+   stack_base = vma-vm_end + stack_expand;
 #else
-   stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   if (stack_size + stack_expand  rlim_stack)
+   stack_base = vma-vm_end - rlim_stack;
+   else
+   stack_base = vma-vm_start - stack_expand;
 #endif
ret = expand_stack(vma, stack_base);
if (ret)
_

___
Linuxppc-dev mailing list

Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Michael Neuling

   note: it's untested.
  
  Works for me on ppc64 with 4k and 64k pages.  Thanks!
  
  I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
  as well.
 
 There's only one CONFIG_GROWSUP arch - parisc.
 
 Guys, here's the rolled-up patch.  

FYI the rolled up patch still works fine on PPC64.  Thanks.  

 Could someone please test it on parisc?
 
 err, I'm not sure what one needs to do to test it, actually. 
 Presumably it involves setting an unusual `ulimit -s'.  Can someone
 please suggest a test plan?

How about doing:
  'ulimit -s 15; ls'
before and after the patch is applied.  Before it's applied, 'ls' should
be killed.  After the patch is applied, 'ls' should no longer be killed.

I'm suggesting a stack limit of 15KB since it's small enough to trigger
20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
case to handle correctly with this code.

4K pages on parisc should be fine to test with.

Mikey

 
 From: Michael Neuling mi...@neuling.org
 
 When reserving stack space for a new process, make sure we're not
 attempting to expand the stack by more than rlimit allows.
 
 This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba (mm:
 variable length argument support) and unmasked by
 fc63cf237078c86214abcb2ee9926d8ad289da9b (exec: setup_arg_pages() fails
 to return errors).
 
 This bug means that when limiting the stack to less the 20*PAGE_SIZE (eg. 
 80K on 4K pages or 'ulimit -s 79') all processes will be killed before
 they start.  This is particularly bad with 64K pages, where a ulimit below
 1280K will kill every process.
 
 Signed-off-by: Michael Neuling mi...@neuling.org
 Cc: KOSAKI Motohiro kosaki.motoh...@jp.fujitsu.com
 Cc: Americo Wang xiyou.wangc...@gmail.com
 Cc: Anton Blanchard an...@samba.org
 Cc: Oleg Nesterov o...@redhat.com
 Cc: James Morris jmor...@namei.org
 Cc: Ingo Molnar mi...@elte.hu
 Cc: Serge Hallyn se...@us.ibm.com
 Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
 Cc: sta...@kernel.org
 
  fs/exec.c |   21 +++--
  1 file changed, 19 insertions(+), 2 deletions(-)
 
 diff -puN fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit
 fs/exec.c
 --- a/fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit
 +++ a/fs/exec.c
 @@ -571,6 +571,9 @@ int setup_arg_pages(struct linux_binprm 
   struct vm_area_struct *prev = NULL;
   unsigned long vm_flags;
   unsigned long stack_base;
 + unsigned long stack_size;
 + unsigned long stack_expand;
 + unsigned long rlim_stack;
  
  #ifdef CONFIG_STACK_GROWSUP
   /* Limit stack size to 1GB */
 @@ -627,10 +630,24 @@ int setup_arg_pages(struct linux_binprm 
   goto out_unlock;
   }
  
 + stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + stack_size = vma-vm_end - vma-vm_start;
 + /*
 +  * Align this down to a page boundary as expand_stack
 +  * will align it up.
 +  */
 + rlim_stack = rlimit(RLIMIT_STACK)  PAGE_MASK;
 + rlim_stack = min(rlim_stack, stack_size);
  #ifdef CONFIG_STACK_GROWSUP
 - stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + if (stack_size + stack_expand  rlim_stack)
 + stack_base = vma-vm_start + rlim_stack;
 + else
 + stack_base = vma-vm_end + stack_expand;
  #else
 - stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + if (stack_size + stack_expand  rlim_stack)
 + stack_base = vma-vm_end - rlim_stack;
 + else
 + stack_base = vma-vm_start - stack_expand;
  #endif
   ret = expand_stack(vma, stack_base);
   if (ret)
 _
 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Helge Deller

On 02/09/2010 10:51 PM, Michael Neuling wrote:

I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
as well.


There's only one CONFIG_GROWSUP arch - parisc.
Could someone please test it on parisc?


I did.


How about doing:
   'ulimit -s 15; ls'
before and after the patch is applied.  Before it's applied, 'ls' should
be killed.  After the patch is applied, 'ls' should no longer be killed.

I'm suggesting a stack limit of 15KB since it's small enough to trigger
20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
case to handle correctly with this code.

4K pages on parisc should be fine to test with.


Mikey, thanks for the suggested test plan.

I'm not sure if your patch does it correct for parisc/stack-grows-up-case.

I tested your patch on  a 4k pages kernel:
r...@c3000:~# uname -a
Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Linux

Without your patch:
r...@c3000:~# ulimit -s 15; ls
Killed
- correct.

With your patch:
r...@c3000:~# ulimit -s 15; ls
Killed
_or_:
r...@c3000:~# ulimit -s 15; ls
Segmentation fault
- ??

Any idea?

Helge



From: Michael Neulingmi...@neuling.org

When reserving stack space for a new process, make sure we're not
attempting to expand the stack by more than rlimit allows.

This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba (mm:
variable length argument support) and unmasked by
fc63cf237078c86214abcb2ee9926d8ad289da9b (exec: setup_arg_pages() fails
to return errors).

This bug means that when limiting the stack to less the 20*PAGE_SIZE (eg.
80K on 4K pages or 'ulimit -s 79') all processes will be killed before
they start.  This is particularly bad with 64K pages, where a ulimit below
1280K will kill every process.

Signed-off-by: Michael Neulingmi...@neuling.org
Cc: KOSAKI Motohirokosaki.motoh...@jp.fujitsu.com
Cc: Americo Wangxiyou.wangc...@gmail.com
Cc: Anton Blanchardan...@samba.org
Cc: Oleg Nesterovo...@redhat.com
Cc: James Morrisjmor...@namei.org
Cc: Ingo Molnarmi...@elte.hu
Cc: Serge Hallynse...@us.ibm.com
Cc: Benjamin Herrenschmidtb...@kernel.crashing.org
Cc:sta...@kernel.org

  fs/exec.c |   21 +++--
  1 file changed, 19 insertions(+), 2 deletions(-)

diff -puN fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit

  fs/exec.c

--- a/fs/exec.c~fs-execc-restrict-initial-stack-space-expansion-to-rlimit
+++ a/fs/exec.c
@@ -571,6 +571,9 @@ int setup_arg_pages(struct linux_binprm
struct vm_area_struct *prev = NULL;
unsigned long vm_flags;
unsigned long stack_base;
+   unsigned long stack_size;
+   unsigned long stack_expand;
+   unsigned long rlim_stack;

  #ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
@@ -627,10 +630,24 @@ int setup_arg_pages(struct linux_binprm
goto out_unlock;
}

+   stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_size = vma-vm_end - vma-vm_start;
+   /*
+* Align this down to a page boundary as expand_stack
+* will align it up.
+*/
+   rlim_stack = rlimit(RLIMIT_STACK)  PAGE_MASK;
+   rlim_stack = min(rlim_stack, stack_size);
  #ifdef CONFIG_STACK_GROWSUP
-   stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   if (stack_size + stack_expand  rlim_stack)
+   stack_base = vma-vm_start + rlim_stack;
+   else
+   stack_base = vma-vm_end + stack_expand;
  #else
-   stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   if (stack_size + stack_expand  rlim_stack)
+   stack_base = vma-vm_end - rlim_stack;
+   else
+   stack_base = vma-vm_start - stack_expand;
  #endif
ret = expand_stack(vma, stack_base);
if (ret)

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread KOSAKI Motohiro
 On 02/09/2010 10:51 PM, Michael Neuling wrote:
  I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
  as well.
 
  There's only one CONFIG_GROWSUP arch - parisc.
  Could someone please test it on parisc?
 
 I did.
 
  How about doing:
 'ulimit -s 15; ls'
  before and after the patch is applied.  Before it's applied, 'ls' should
  be killed.  After the patch is applied, 'ls' should no longer be killed.
 
  I'm suggesting a stack limit of 15KB since it's small enough to trigger
  20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
  case to handle correctly with this code.
 
  4K pages on parisc should be fine to test with.
 
 Mikey, thanks for the suggested test plan.
 
 I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
 
 I tested your patch on  a 4k pages kernel:
 r...@c3000:~# uname -a
 Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Linux
 
 Without your patch:
 r...@c3000:~# ulimit -s 15; ls
 Killed
 - correct.
 
 With your patch:
 r...@c3000:~# ulimit -s 15; ls
 Killed
 _or_:
 r...@c3000:~# ulimit -s 15; ls
 Segmentation fault
 - ??
 
 Any idea?

My x86_64 box also makes segmentation fault. I think ulimit -s 15 is too 
small stack for ls.
ulimit -s 27; ls   wroks perfectly fine.



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Michael Neuling


In message 20100210141016.4d18.a69d9...@jp.fujitsu.com you wrote:
  On 02/09/2010 10:51 PM, Michael Neuling wrote:
   I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
   as well.
  
   There's only one CONFIG_GROWSUP arch - parisc.
   Could someone please test it on parisc?
  
  I did.
  
   How about doing:
  'ulimit -s 15; ls'
   before and after the patch is applied.  Before it's applied, 'ls' should
   be killed.  After the patch is applied, 'ls' should no longer be killed.
  
   I'm suggesting a stack limit of 15KB since it's small enough to trigger
   20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
   case to handle correctly with this code.
  
   4K pages on parisc should be fine to test with.
  
  Mikey, thanks for the suggested test plan.
  
  I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
  
  I tested your patch on  a 4k pages kernel:
  r...@c3000:~# uname -a
  Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Li
nux
  
  Without your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  - correct.
  
  With your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  _or_:
  r...@c3000:~# ulimit -s 15; ls
  Segmentation fault
  - ??
  
  Any idea?
 
 My x86_64 box also makes segmentation fault. I think ulimit -s 15 is too sm
all stack for ls.
 ulimit -s 27; ls   wroks perfectly fine.

Arrh.  I asked Helge offline earlier to check what use to work on parisc
on 2.6.31.

I guess PPC has a nice clean non-bloated ABI :-D

Mikey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-09 Thread Michael Neuling


In message 20100210141016.4d18.a69d9...@jp.fujitsu.com you wrote:
  On 02/09/2010 10:51 PM, Michael Neuling wrote:
   I'd still like someone with a CONFIG_STACK_GROWSUP arch to test/ACK it
   as well.
  
   There's only one CONFIG_GROWSUP arch - parisc.
   Could someone please test it on parisc?
  
  I did.
  
   How about doing:
  'ulimit -s 15; ls'
   before and after the patch is applied.  Before it's applied, 'ls' should
   be killed.  After the patch is applied, 'ls' should no longer be killed.
  
   I'm suggesting a stack limit of 15KB since it's small enough to trigger
   20*PAGE_SIZE.  Also 15KB not a multiple of PAGE_SIZE, which is a trickier
   case to handle correctly with this code.
  
   4K pages on parisc should be fine to test with.
  
  Mikey, thanks for the suggested test plan.
  
  I'm not sure if your patch does it correct for parisc/stack-grows-up-case.
  
  I tested your patch on  a 4k pages kernel:
  r...@c3000:~# uname -a
  Linux c3000 2.6.33-rc7-32bit #221 Tue Feb 9 23:17:06 CET 2010 parisc GNU/Li
nux
  
  Without your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  - correct.
  
  With your patch:
  r...@c3000:~# ulimit -s 15; ls
  Killed
  _or_:
  r...@c3000:~# ulimit -s 15; ls
  Segmentation fault
  - ??
  
  Any idea?
 
 My x86_64 box also makes segmentation fault. I think ulimit -s 15 is too sm
all stack for ls.
 ulimit -s 27; ls   wroks perfectly fine.

Arrh.  I asked Helge offline earlier to check what use to work on parisc
on 2.6.31.

I guess PPC has a nice clean non-bloated ABI :-D

Mikey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] Restrict initial stack space expansion to rlimit

2010-02-08 Thread Michael Neuling
When reserving stack space for a new process, make sure we're not
attempting to expand the stack by more than rlimit allows.

This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba mm:
variable length argument support and unmasked by
fc63cf237078c86214abcb2ee9926d8ad289da9b exec: setup_arg_pages() fails
to return errors.  This bug means when limiting the stack to less the
20*PAGE_SIZE (eg. 80K on 4K pages or 'ulimit -s 79') all processes will
be killed before they start.  This is particularly bad with 64K pages,
where a ulimit below 1280K will kill every process.

Signed-off-by: Michael Neuling mi...@neuling.org
Cc: sta...@kernel.org
---
Attempts to answer comments from Kosaki Motohiro.

Tested on PPC only, hence !CONFIG_STACK_GROWSUP.  Someone should
probably ACK for an arch with CONFIG_STACK_GROWSUP.

As noted, stable needs the same patch, but 2.6.32 doesn't have the
rlimit() helper.

 fs/exec.c |   21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

Index: linux-2.6-ozlabs/fs/exec.c
===
--- linux-2.6-ozlabs.orig/fs/exec.c
+++ linux-2.6-ozlabs/fs/exec.c
@@ -555,6 +555,7 @@ static int shift_arg_pages(struct vm_are
 }
 
 #define EXTRA_STACK_VM_PAGES   20  /* random */
+#define ALIGN_DOWN(addr,size)  ((addr)(~((size)-1)))
 
 /*
  * Finalizes the stack vm_area_struct. The flags and permissions are updated,
@@ -570,7 +571,7 @@ int setup_arg_pages(struct linux_binprm 
struct vm_area_struct *vma = bprm-vma;
struct vm_area_struct *prev = NULL;
unsigned long vm_flags;
-   unsigned long stack_base;
+   unsigned long stack_base, stack_expand, stack_expand_lim, stack_size;
 
 #ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
@@ -627,10 +628,24 @@ int setup_arg_pages(struct linux_binprm 
goto out_unlock;
}
 
+   stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_size = vma-vm_end - vma-vm_start;
+   if (rlimit(RLIMIT_STACK)  stack_size)
+   stack_expand_lim = 0; /* don't shrick the stack */
+   else
+   /*
+* Align this down to a page boundary as expand_stack
+* will align it up.
+*/
+   stack_expand_lim = ALIGN_DOWN(rlimit(RLIMIT_STACK) - stack_size,
+ PAGE_SIZE);
+   /* Initial stack must not cause stack overflow. */
+   if (stack_expand  stack_expand_lim)
+   stack_expand = stack_expand_lim;
 #ifdef CONFIG_STACK_GROWSUP
-   stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_base = vma-vm_end + stack_expand;
 #else
-   stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_base = vma-vm_start - stack_expand;
 #endif
ret = expand_stack(vma, stack_base);
if (ret)
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] Restrict initial stack space expansion to rlimit

2010-02-08 Thread KOSAKI Motohiro
 When reserving stack space for a new process, make sure we're not
 attempting to expand the stack by more than rlimit allows.
 
 This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba mm:
 variable length argument support and unmasked by
 fc63cf237078c86214abcb2ee9926d8ad289da9b exec: setup_arg_pages() fails
 to return errors.  This bug means when limiting the stack to less the
 20*PAGE_SIZE (eg. 80K on 4K pages or 'ulimit -s 79') all processes will
 be killed before they start.  This is particularly bad with 64K pages,
 where a ulimit below 1280K will kill every process.
 
 Signed-off-by: Michael Neuling mi...@neuling.org
 Cc: sta...@kernel.org
 ---
 Attempts to answer comments from Kosaki Motohiro.
 
 Tested on PPC only, hence !CONFIG_STACK_GROWSUP.  Someone should
 probably ACK for an arch with CONFIG_STACK_GROWSUP.
 
 As noted, stable needs the same patch, but 2.6.32 doesn't have the
 rlimit() helper.
 
  fs/exec.c |   21 ++---
  1 file changed, 18 insertions(+), 3 deletions(-)
 
 Index: linux-2.6-ozlabs/fs/exec.c
 ===
 --- linux-2.6-ozlabs.orig/fs/exec.c
 +++ linux-2.6-ozlabs/fs/exec.c
 @@ -555,6 +555,7 @@ static int shift_arg_pages(struct vm_are
  }
  
  #define EXTRA_STACK_VM_PAGES 20  /* random */
 +#define ALIGN_DOWN(addr,size)((addr)(~((size)-1)))
  
  /*
   * Finalizes the stack vm_area_struct. The flags and permissions are updated,
 @@ -570,7 +571,7 @@ int setup_arg_pages(struct linux_binprm 
   struct vm_area_struct *vma = bprm-vma;
   struct vm_area_struct *prev = NULL;
   unsigned long vm_flags;
 - unsigned long stack_base;
 + unsigned long stack_base, stack_expand, stack_expand_lim, stack_size;
  
  #ifdef CONFIG_STACK_GROWSUP
   /* Limit stack size to 1GB */
 @@ -627,10 +628,24 @@ int setup_arg_pages(struct linux_binprm 
   goto out_unlock;
   }
  
 + stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + stack_size = vma-vm_end - vma-vm_start;
 + if (rlimit(RLIMIT_STACK)  stack_size)
 + stack_expand_lim = 0; /* don't shrick the stack */
 + else
 + /*
 +  * Align this down to a page boundary as expand_stack
 +  * will align it up.
 +  */
 + stack_expand_lim = ALIGN_DOWN(rlimit(RLIMIT_STACK) - stack_size,
 +   PAGE_SIZE);
 + /* Initial stack must not cause stack overflow. */
 + if (stack_expand  stack_expand_lim)
 + stack_expand = stack_expand_lim;
  #ifdef CONFIG_STACK_GROWSUP
 - stack_base = vma-vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + stack_base = vma-vm_end + stack_expand;
  #else
 - stack_base = vma-vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE;
 + stack_base = vma-vm_start - stack_expand;
  #endif
   ret = expand_stack(vma, stack_base);
   if (ret)

Umm.. It looks correct. but the nested complex if statement seems a bit ugly.
Instead, How about following?

note: it's untested.



===
From: Michael Neuling mi...@neuling.org
Subject: Restrict initial stack space expansion to rlimit

When reserving stack space for a new process, make sure we're not
attempting to expand the stack by more than rlimit allows.

This fixes a bug caused by b6a2fea39318e43fee84fa7b0b90d68bed92d2ba mm:
variable length argument support and unmasked by
fc63cf237078c86214abcb2ee9926d8ad289da9b exec: setup_arg_pages() fails
to return errors.  This bug means when limiting the stack to less the
20*PAGE_SIZE (eg. 80K on 4K pages or 'ulimit -s 79') all processes will
be killed before they start.  This is particularly bad with 64K pages,
where a ulimit below 1280K will kill every process.

[kosaki.motoh...@jp.fujitsu.com: cleanups]
Signed-off-by: Michael Neuling mi...@neuling.org
Signed-off-by: KOSAKI Motohiro kosaki.motoh...@jp.fujitsu.com
Cc: sta...@kernel.org
---
Attempts to answer comments from Kosaki Motohiro.

Tested on PPC only, hence !CONFIG_STACK_GROWSUP.  Someone should
probably ACK for an arch with CONFIG_STACK_GROWSUP.

As noted, stable needs the same patch, but 2.6.32 doesn't have the
rlimit() helper.

diff --git a/fs/exec.c b/fs/exec.c
index 6f7fb0c..325bad4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -573,6 +573,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
struct vm_area_struct *prev = NULL;
unsigned long vm_flags;
unsigned long stack_base;
+   unsigned long stack_size;
+   unsigned long stack_expand;
+   unsigned long rlim_stack;
 
 #ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
@@ -629,10 +632,27 @@ int setup_arg_pages(struct linux_binprm *bprm,
goto out_unlock;
}
 
+   stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+   stack_size = vma-vm_end - vma-vm_start;
+   /*
+* Align this down to a page boundary as expand_stack
+* will align it up.
+*/