diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 30 |
1 files changed, 23 insertions, 7 deletions
@@ -571,6 +571,9 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
571 | struct vm_area_struct *prev = NULL; | 571 | struct vm_area_struct *prev = NULL; |
572 | unsigned long vm_flags; | 572 | unsigned long vm_flags; |
573 | unsigned long stack_base; | 573 | unsigned long stack_base; |
574 | unsigned long stack_size; | ||
575 | unsigned long stack_expand; | ||
576 | unsigned long rlim_stack; | ||
574 | 577 | ||
575 | #ifdef CONFIG_STACK_GROWSUP | 578 | #ifdef CONFIG_STACK_GROWSUP |
576 | /* Limit stack size to 1GB */ | 579 | /* Limit stack size to 1GB */ |
@@ -627,10 +630,23 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
627 | goto out_unlock; | 630 | goto out_unlock; |
628 | } | 631 | } |
629 | 632 | ||
633 | stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE; | ||
634 | stack_size = vma->vm_end - vma->vm_start; | ||
635 | /* | ||
636 | * Align this down to a page boundary as expand_stack | ||
637 | * will align it up. | ||
638 | */ | ||
639 | rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK; | ||
630 | #ifdef CONFIG_STACK_GROWSUP | 640 | #ifdef CONFIG_STACK_GROWSUP |
631 | stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE; | 641 | if (stack_size + stack_expand > rlim_stack) |
642 | stack_base = vma->vm_start + rlim_stack; | ||
643 | else | ||
644 | stack_base = vma->vm_end + stack_expand; | ||
632 | #else | 645 | #else |
633 | stack_base = vma->vm_start - EXTRA_STACK_VM_PAGES * PAGE_SIZE; | 646 | if (stack_size + stack_expand > rlim_stack) |
647 | stack_base = vma->vm_end - rlim_stack; | ||
648 | else | ||
649 | stack_base = vma->vm_start - stack_expand; | ||
634 | #endif | 650 | #endif |
635 | ret = expand_stack(vma, stack_base); | 651 | ret = expand_stack(vma, stack_base); |
636 | if (ret) | 652 | if (ret) |
@@ -961,6 +977,11 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
961 | goto out; | 977 | goto out; |
962 | 978 | ||
963 | bprm->mm = NULL; /* We're using it now */ | 979 | bprm->mm = NULL; /* We're using it now */ |
980 | |||
981 | current->flags &= ~PF_RANDOMIZE; | ||
982 | flush_thread(); | ||
983 | current->personality &= ~bprm->per_clear; | ||
984 | |||
964 | return 0; | 985 | return 0; |
965 | 986 | ||
966 | out: | 987 | out: |
@@ -997,9 +1018,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
997 | tcomm[i] = '\0'; | 1018 | tcomm[i] = '\0'; |
998 | set_task_comm(current, tcomm); | 1019 | set_task_comm(current, tcomm); |
999 | 1020 | ||
1000 | current->flags &= ~PF_RANDOMIZE; | ||
1001 | flush_thread(); | ||
1002 | |||
1003 | /* Set the new mm task size. We have to do that late because it may | 1021 | /* Set the new mm task size. We have to do that late because it may |
1004 | * depend on TIF_32BIT which is only updated in flush_thread() on | 1022 | * depend on TIF_32BIT which is only updated in flush_thread() on |
1005 | * some architectures like powerpc | 1023 | * some architectures like powerpc |
@@ -1015,8 +1033,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
1015 | set_dumpable(current->mm, suid_dumpable); | 1033 | set_dumpable(current->mm, suid_dumpable); |
1016 | } | 1034 | } |
1017 | 1035 | ||
1018 | current->personality &= ~bprm->per_clear; | ||
1019 | |||
1020 | /* | 1036 | /* |
1021 | * Flush performance counters when crossing a | 1037 | * Flush performance counters when crossing a |
1022 | * security domain: | 1038 | * security domain: |