diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 56 |
1 files changed, 39 insertions, 17 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) |
| @@ -941,9 +957,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) | |||
| 941 | 957 | ||
| 942 | int flush_old_exec(struct linux_binprm * bprm) | 958 | int flush_old_exec(struct linux_binprm * bprm) |
| 943 | { | 959 | { |
| 944 | char * name; | 960 | int retval; |
| 945 | int i, ch, retval; | ||
| 946 | char tcomm[sizeof(current->comm)]; | ||
| 947 | 961 | ||
| 948 | /* | 962 | /* |
| 949 | * Make sure we have a private signal table and that | 963 | * Make sure we have a private signal table and that |
| @@ -964,6 +978,25 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 964 | 978 | ||
| 965 | bprm->mm = NULL; /* We're using it now */ | 979 | bprm->mm = NULL; /* We're using it now */ |
| 966 | 980 | ||
| 981 | current->flags &= ~PF_RANDOMIZE; | ||
| 982 | flush_thread(); | ||
| 983 | current->personality &= ~bprm->per_clear; | ||
| 984 | |||
| 985 | return 0; | ||
| 986 | |||
| 987 | out: | ||
| 988 | return retval; | ||
| 989 | } | ||
| 990 | EXPORT_SYMBOL(flush_old_exec); | ||
| 991 | |||
| 992 | void setup_new_exec(struct linux_binprm * bprm) | ||
| 993 | { | ||
| 994 | int i, ch; | ||
| 995 | char * name; | ||
| 996 | char tcomm[sizeof(current->comm)]; | ||
| 997 | |||
| 998 | arch_pick_mmap_layout(current->mm); | ||
| 999 | |||
| 967 | /* This is the point of no return */ | 1000 | /* This is the point of no return */ |
| 968 | current->sas_ss_sp = current->sas_ss_size = 0; | 1001 | current->sas_ss_sp = current->sas_ss_size = 0; |
| 969 | 1002 | ||
| @@ -985,9 +1018,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 985 | tcomm[i] = '\0'; | 1018 | tcomm[i] = '\0'; |
| 986 | set_task_comm(current, tcomm); | 1019 | set_task_comm(current, tcomm); |
| 987 | 1020 | ||
| 988 | current->flags &= ~PF_RANDOMIZE; | ||
| 989 | flush_thread(); | ||
| 990 | |||
| 991 | /* 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 |
| 992 | * 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 |
| 993 | * some architectures like powerpc | 1023 | * some architectures like powerpc |
| @@ -1003,8 +1033,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 1003 | set_dumpable(current->mm, suid_dumpable); | 1033 | set_dumpable(current->mm, suid_dumpable); |
| 1004 | } | 1034 | } |
| 1005 | 1035 | ||
| 1006 | current->personality &= ~bprm->per_clear; | ||
| 1007 | |||
| 1008 | /* | 1036 | /* |
| 1009 | * Flush performance counters when crossing a | 1037 | * Flush performance counters when crossing a |
| 1010 | * security domain: | 1038 | * security domain: |
| @@ -1019,14 +1047,8 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 1019 | 1047 | ||
| 1020 | flush_signal_handlers(current, 0); | 1048 | flush_signal_handlers(current, 0); |
| 1021 | flush_old_files(current->files); | 1049 | flush_old_files(current->files); |
| 1022 | |||
| 1023 | return 0; | ||
| 1024 | |||
| 1025 | out: | ||
| 1026 | return retval; | ||
| 1027 | } | 1050 | } |
| 1028 | 1051 | EXPORT_SYMBOL(setup_new_exec); | |
| 1029 | EXPORT_SYMBOL(flush_old_exec); | ||
| 1030 | 1052 | ||
| 1031 | /* | 1053 | /* |
| 1032 | * Prepare credentials and lock ->cred_guard_mutex. | 1054 | * Prepare credentials and lock ->cred_guard_mutex. |
