diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 96 |
1 files changed, 62 insertions, 34 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) |
@@ -826,7 +842,9 @@ static int de_thread(struct task_struct *tsk) | |||
826 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); | 842 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); |
827 | transfer_pid(leader, tsk, PIDTYPE_PGID); | 843 | transfer_pid(leader, tsk, PIDTYPE_PGID); |
828 | transfer_pid(leader, tsk, PIDTYPE_SID); | 844 | transfer_pid(leader, tsk, PIDTYPE_SID); |
845 | |||
829 | list_replace_rcu(&leader->tasks, &tsk->tasks); | 846 | list_replace_rcu(&leader->tasks, &tsk->tasks); |
847 | list_replace_init(&leader->sibling, &tsk->sibling); | ||
830 | 848 | ||
831 | tsk->group_leader = tsk; | 849 | tsk->group_leader = tsk; |
832 | leader->group_leader = tsk; | 850 | leader->group_leader = tsk; |
@@ -939,9 +957,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) | |||
939 | 957 | ||
940 | int flush_old_exec(struct linux_binprm * bprm) | 958 | int flush_old_exec(struct linux_binprm * bprm) |
941 | { | 959 | { |
942 | char * name; | 960 | int retval; |
943 | int i, ch, retval; | ||
944 | char tcomm[sizeof(current->comm)]; | ||
945 | 961 | ||
946 | /* | 962 | /* |
947 | * Make sure we have a private signal table and that | 963 | * Make sure we have a private signal table and that |
@@ -962,6 +978,25 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
962 | 978 | ||
963 | bprm->mm = NULL; /* We're using it now */ | 979 | bprm->mm = NULL; /* We're using it now */ |
964 | 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 | |||
965 | /* This is the point of no return */ | 1000 | /* This is the point of no return */ |
966 | current->sas_ss_sp = current->sas_ss_size = 0; | 1001 | current->sas_ss_sp = current->sas_ss_size = 0; |
967 | 1002 | ||
@@ -983,9 +1018,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
983 | tcomm[i] = '\0'; | 1018 | tcomm[i] = '\0'; |
984 | set_task_comm(current, tcomm); | 1019 | set_task_comm(current, tcomm); |
985 | 1020 | ||
986 | current->flags &= ~PF_RANDOMIZE; | ||
987 | flush_thread(); | ||
988 | |||
989 | /* 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 |
990 | * 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 |
991 | * some architectures like powerpc | 1023 | * some architectures like powerpc |
@@ -1001,8 +1033,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1001 | set_dumpable(current->mm, suid_dumpable); | 1033 | set_dumpable(current->mm, suid_dumpable); |
1002 | } | 1034 | } |
1003 | 1035 | ||
1004 | current->personality &= ~bprm->per_clear; | ||
1005 | |||
1006 | /* | 1036 | /* |
1007 | * Flush performance counters when crossing a | 1037 | * Flush performance counters when crossing a |
1008 | * security domain: | 1038 | * security domain: |
@@ -1017,14 +1047,8 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1017 | 1047 | ||
1018 | flush_signal_handlers(current, 0); | 1048 | flush_signal_handlers(current, 0); |
1019 | flush_old_files(current->files); | 1049 | flush_old_files(current->files); |
1020 | |||
1021 | return 0; | ||
1022 | |||
1023 | out: | ||
1024 | return retval; | ||
1025 | } | 1050 | } |
1026 | 1051 | EXPORT_SYMBOL(setup_new_exec); | |
1027 | EXPORT_SYMBOL(flush_old_exec); | ||
1028 | 1052 | ||
1029 | /* | 1053 | /* |
1030 | * Prepare credentials and lock ->cred_guard_mutex. | 1054 | * Prepare credentials and lock ->cred_guard_mutex. |
@@ -1761,17 +1785,20 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1761 | struct mm_struct *mm = current->mm; | 1785 | struct mm_struct *mm = current->mm; |
1762 | struct linux_binfmt * binfmt; | 1786 | struct linux_binfmt * binfmt; |
1763 | struct inode * inode; | 1787 | struct inode * inode; |
1764 | struct file * file; | ||
1765 | const struct cred *old_cred; | 1788 | const struct cred *old_cred; |
1766 | struct cred *cred; | 1789 | struct cred *cred; |
1767 | int retval = 0; | 1790 | int retval = 0; |
1768 | int flag = 0; | 1791 | int flag = 0; |
1769 | int ispipe = 0; | 1792 | int ispipe = 0; |
1770 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | ||
1771 | char **helper_argv = NULL; | 1793 | char **helper_argv = NULL; |
1772 | int helper_argc = 0; | 1794 | int helper_argc = 0; |
1773 | int dump_count = 0; | 1795 | int dump_count = 0; |
1774 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 1796 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
1797 | struct coredump_params cprm = { | ||
1798 | .signr = signr, | ||
1799 | .regs = regs, | ||
1800 | .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, | ||
1801 | }; | ||
1775 | 1802 | ||
1776 | audit_core_dumps(signr); | 1803 | audit_core_dumps(signr); |
1777 | 1804 | ||
@@ -1827,15 +1854,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1827 | ispipe = format_corename(corename, signr); | 1854 | ispipe = format_corename(corename, signr); |
1828 | unlock_kernel(); | 1855 | unlock_kernel(); |
1829 | 1856 | ||
1830 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) | 1857 | if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) |
1831 | goto fail_unlock; | 1858 | goto fail_unlock; |
1832 | 1859 | ||
1833 | if (ispipe) { | 1860 | if (ispipe) { |
1834 | if (core_limit == 0) { | 1861 | if (cprm.limit == 0) { |
1835 | /* | 1862 | /* |
1836 | * Normally core limits are irrelevant to pipes, since | 1863 | * Normally core limits are irrelevant to pipes, since |
1837 | * we're not writing to the file system, but we use | 1864 | * we're not writing to the file system, but we use |
1838 | * core_limit of 0 here as a speacial value. Any | 1865 | * cprm.limit of 0 here as a speacial value. Any |
1839 | * non-zero limit gets set to RLIM_INFINITY below, but | 1866 | * non-zero limit gets set to RLIM_INFINITY below, but |
1840 | * a limit of 0 skips the dump. This is a consistent | 1867 | * a limit of 0 skips the dump. This is a consistent |
1841 | * way to catch recursive crashes. We can still crash | 1868 | * way to catch recursive crashes. We can still crash |
@@ -1868,25 +1895,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1868 | goto fail_dropcount; | 1895 | goto fail_dropcount; |
1869 | } | 1896 | } |
1870 | 1897 | ||
1871 | core_limit = RLIM_INFINITY; | 1898 | cprm.limit = RLIM_INFINITY; |
1872 | 1899 | ||
1873 | /* SIGPIPE can happen, but it's just never processed */ | 1900 | /* SIGPIPE can happen, but it's just never processed */ |
1874 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, | 1901 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, |
1875 | &file)) { | 1902 | &cprm.file)) { |
1876 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1903 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1877 | corename); | 1904 | corename); |
1878 | goto fail_dropcount; | 1905 | goto fail_dropcount; |
1879 | } | 1906 | } |
1880 | } else | 1907 | } else |
1881 | file = filp_open(corename, | 1908 | cprm.file = filp_open(corename, |
1882 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 1909 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1883 | 0600); | 1910 | 0600); |
1884 | if (IS_ERR(file)) | 1911 | if (IS_ERR(cprm.file)) |
1885 | goto fail_dropcount; | 1912 | goto fail_dropcount; |
1886 | inode = file->f_path.dentry->d_inode; | 1913 | inode = cprm.file->f_path.dentry->d_inode; |
1887 | if (inode->i_nlink > 1) | 1914 | if (inode->i_nlink > 1) |
1888 | goto close_fail; /* multiple links - don't dump */ | 1915 | goto close_fail; /* multiple links - don't dump */ |
1889 | if (!ispipe && d_unhashed(file->f_path.dentry)) | 1916 | if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) |
1890 | goto close_fail; | 1917 | goto close_fail; |
1891 | 1918 | ||
1892 | /* AK: actually i see no reason to not allow this for named pipes etc., | 1919 | /* AK: actually i see no reason to not allow this for named pipes etc., |
@@ -1899,21 +1926,22 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1899 | */ | 1926 | */ |
1900 | if (inode->i_uid != current_fsuid()) | 1927 | if (inode->i_uid != current_fsuid()) |
1901 | goto close_fail; | 1928 | goto close_fail; |
1902 | if (!file->f_op) | 1929 | if (!cprm.file->f_op) |
1903 | goto close_fail; | 1930 | goto close_fail; |
1904 | if (!file->f_op->write) | 1931 | if (!cprm.file->f_op->write) |
1905 | goto close_fail; | 1932 | goto close_fail; |
1906 | if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) | 1933 | if (!ispipe && |
1934 | do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0) | ||
1907 | goto close_fail; | 1935 | goto close_fail; |
1908 | 1936 | ||
1909 | retval = binfmt->core_dump(signr, regs, file, core_limit); | 1937 | retval = binfmt->core_dump(&cprm); |
1910 | 1938 | ||
1911 | if (retval) | 1939 | if (retval) |
1912 | current->signal->group_exit_code |= 0x80; | 1940 | current->signal->group_exit_code |= 0x80; |
1913 | close_fail: | 1941 | close_fail: |
1914 | if (ispipe && core_pipe_limit) | 1942 | if (ispipe && core_pipe_limit) |
1915 | wait_for_dump_helpers(file); | 1943 | wait_for_dump_helpers(cprm.file); |
1916 | filp_close(file, NULL); | 1944 | filp_close(cprm.file, NULL); |
1917 | fail_dropcount: | 1945 | fail_dropcount: |
1918 | if (dump_count) | 1946 | if (dump_count) |
1919 | atomic_dec(&core_dump_count); | 1947 | atomic_dec(&core_dump_count); |