diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 117 |
1 files changed, 74 insertions, 43 deletions
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/proc_fs.h> | 46 | #include <linux/proc_fs.h> |
47 | #include <linux/mount.h> | 47 | #include <linux/mount.h> |
48 | #include <linux/security.h> | 48 | #include <linux/security.h> |
49 | #include <linux/ima.h> | ||
50 | #include <linux/syscalls.h> | 49 | #include <linux/syscalls.h> |
51 | #include <linux/tsacct_kern.h> | 50 | #include <linux/tsacct_kern.h> |
52 | #include <linux/cn_proc.h> | 51 | #include <linux/cn_proc.h> |
@@ -572,6 +571,9 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
572 | struct vm_area_struct *prev = NULL; | 571 | struct vm_area_struct *prev = NULL; |
573 | unsigned long vm_flags; | 572 | unsigned long vm_flags; |
574 | unsigned long stack_base; | 573 | unsigned long stack_base; |
574 | unsigned long stack_size; | ||
575 | unsigned long stack_expand; | ||
576 | unsigned long rlim_stack; | ||
575 | 577 | ||
576 | #ifdef CONFIG_STACK_GROWSUP | 578 | #ifdef CONFIG_STACK_GROWSUP |
577 | /* Limit stack size to 1GB */ | 579 | /* Limit stack size to 1GB */ |
@@ -624,16 +626,27 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
624 | /* Move stack pages down in memory. */ | 626 | /* Move stack pages down in memory. */ |
625 | if (stack_shift) { | 627 | if (stack_shift) { |
626 | ret = shift_arg_pages(vma, stack_shift); | 628 | ret = shift_arg_pages(vma, stack_shift); |
627 | if (ret) { | 629 | if (ret) |
628 | up_write(&mm->mmap_sem); | 630 | goto out_unlock; |
629 | return ret; | ||
630 | } | ||
631 | } | 631 | } |
632 | 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; | ||
633 | #ifdef CONFIG_STACK_GROWSUP | 640 | #ifdef CONFIG_STACK_GROWSUP |
634 | 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; | ||
635 | #else | 645 | #else |
636 | 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; | ||
637 | #endif | 650 | #endif |
638 | ret = expand_stack(vma, stack_base); | 651 | ret = expand_stack(vma, stack_base); |
639 | if (ret) | 652 | if (ret) |
@@ -641,7 +654,7 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
641 | 654 | ||
642 | out_unlock: | 655 | out_unlock: |
643 | up_write(&mm->mmap_sem); | 656 | up_write(&mm->mmap_sem); |
644 | return 0; | 657 | return ret; |
645 | } | 658 | } |
646 | EXPORT_SYMBOL(setup_arg_pages); | 659 | EXPORT_SYMBOL(setup_arg_pages); |
647 | 660 | ||
@@ -829,7 +842,9 @@ static int de_thread(struct task_struct *tsk) | |||
829 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); | 842 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); |
830 | transfer_pid(leader, tsk, PIDTYPE_PGID); | 843 | transfer_pid(leader, tsk, PIDTYPE_PGID); |
831 | transfer_pid(leader, tsk, PIDTYPE_SID); | 844 | transfer_pid(leader, tsk, PIDTYPE_SID); |
845 | |||
832 | list_replace_rcu(&leader->tasks, &tsk->tasks); | 846 | list_replace_rcu(&leader->tasks, &tsk->tasks); |
847 | list_replace_init(&leader->sibling, &tsk->sibling); | ||
833 | 848 | ||
834 | tsk->group_leader = tsk; | 849 | tsk->group_leader = tsk; |
835 | leader->group_leader = tsk; | 850 | leader->group_leader = tsk; |
@@ -926,6 +941,15 @@ char *get_task_comm(char *buf, struct task_struct *tsk) | |||
926 | void set_task_comm(struct task_struct *tsk, char *buf) | 941 | void set_task_comm(struct task_struct *tsk, char *buf) |
927 | { | 942 | { |
928 | task_lock(tsk); | 943 | task_lock(tsk); |
944 | |||
945 | /* | ||
946 | * Threads may access current->comm without holding | ||
947 | * the task lock, so write the string carefully. | ||
948 | * Readers without a lock may see incomplete new | ||
949 | * names but are safe from non-terminating string reads. | ||
950 | */ | ||
951 | memset(tsk->comm, 0, TASK_COMM_LEN); | ||
952 | wmb(); | ||
929 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); | 953 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); |
930 | task_unlock(tsk); | 954 | task_unlock(tsk); |
931 | perf_event_comm(tsk); | 955 | perf_event_comm(tsk); |
@@ -933,9 +957,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) | |||
933 | 957 | ||
934 | int flush_old_exec(struct linux_binprm * bprm) | 958 | int flush_old_exec(struct linux_binprm * bprm) |
935 | { | 959 | { |
936 | char * name; | 960 | int retval; |
937 | int i, ch, retval; | ||
938 | char tcomm[sizeof(current->comm)]; | ||
939 | 961 | ||
940 | /* | 962 | /* |
941 | * Make sure we have a private signal table and that | 963 | * Make sure we have a private signal table and that |
@@ -956,6 +978,25 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
956 | 978 | ||
957 | bprm->mm = NULL; /* We're using it now */ | 979 | bprm->mm = NULL; /* We're using it now */ |
958 | 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 | |||
959 | /* This is the point of no return */ | 1000 | /* This is the point of no return */ |
960 | current->sas_ss_sp = current->sas_ss_size = 0; | 1001 | current->sas_ss_sp = current->sas_ss_size = 0; |
961 | 1002 | ||
@@ -977,9 +1018,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
977 | tcomm[i] = '\0'; | 1018 | tcomm[i] = '\0'; |
978 | set_task_comm(current, tcomm); | 1019 | set_task_comm(current, tcomm); |
979 | 1020 | ||
980 | current->flags &= ~PF_RANDOMIZE; | ||
981 | flush_thread(); | ||
982 | |||
983 | /* 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 |
984 | * 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 |
985 | * some architectures like powerpc | 1023 | * some architectures like powerpc |
@@ -995,8 +1033,6 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
995 | set_dumpable(current->mm, suid_dumpable); | 1033 | set_dumpable(current->mm, suid_dumpable); |
996 | } | 1034 | } |
997 | 1035 | ||
998 | current->personality &= ~bprm->per_clear; | ||
999 | |||
1000 | /* | 1036 | /* |
1001 | * Flush performance counters when crossing a | 1037 | * Flush performance counters when crossing a |
1002 | * security domain: | 1038 | * security domain: |
@@ -1011,14 +1047,8 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1011 | 1047 | ||
1012 | flush_signal_handlers(current, 0); | 1048 | flush_signal_handlers(current, 0); |
1013 | flush_old_files(current->files); | 1049 | flush_old_files(current->files); |
1014 | |||
1015 | return 0; | ||
1016 | |||
1017 | out: | ||
1018 | return retval; | ||
1019 | } | 1050 | } |
1020 | 1051 | EXPORT_SYMBOL(setup_new_exec); | |
1021 | EXPORT_SYMBOL(flush_old_exec); | ||
1022 | 1052 | ||
1023 | /* | 1053 | /* |
1024 | * Prepare credentials and lock ->cred_guard_mutex. | 1054 | * Prepare credentials and lock ->cred_guard_mutex. |
@@ -1211,9 +1241,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
1211 | retval = security_bprm_check(bprm); | 1241 | retval = security_bprm_check(bprm); |
1212 | if (retval) | 1242 | if (retval) |
1213 | return retval; | 1243 | return retval; |
1214 | retval = ima_bprm_check(bprm); | ||
1215 | if (retval) | ||
1216 | return retval; | ||
1217 | 1244 | ||
1218 | /* kernel module loader fixup */ | 1245 | /* kernel module loader fixup */ |
1219 | /* so we don't try to load run modprobe in kernel space. */ | 1246 | /* so we don't try to load run modprobe in kernel space. */ |
@@ -1758,17 +1785,20 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1758 | struct mm_struct *mm = current->mm; | 1785 | struct mm_struct *mm = current->mm; |
1759 | struct linux_binfmt * binfmt; | 1786 | struct linux_binfmt * binfmt; |
1760 | struct inode * inode; | 1787 | struct inode * inode; |
1761 | struct file * file; | ||
1762 | const struct cred *old_cred; | 1788 | const struct cred *old_cred; |
1763 | struct cred *cred; | 1789 | struct cred *cred; |
1764 | int retval = 0; | 1790 | int retval = 0; |
1765 | int flag = 0; | 1791 | int flag = 0; |
1766 | int ispipe = 0; | 1792 | int ispipe = 0; |
1767 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | ||
1768 | char **helper_argv = NULL; | 1793 | char **helper_argv = NULL; |
1769 | int helper_argc = 0; | 1794 | int helper_argc = 0; |
1770 | int dump_count = 0; | 1795 | int dump_count = 0; |
1771 | 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 | }; | ||
1772 | 1802 | ||
1773 | audit_core_dumps(signr); | 1803 | audit_core_dumps(signr); |
1774 | 1804 | ||
@@ -1824,15 +1854,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1824 | ispipe = format_corename(corename, signr); | 1854 | ispipe = format_corename(corename, signr); |
1825 | unlock_kernel(); | 1855 | unlock_kernel(); |
1826 | 1856 | ||
1827 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) | 1857 | if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) |
1828 | goto fail_unlock; | 1858 | goto fail_unlock; |
1829 | 1859 | ||
1830 | if (ispipe) { | 1860 | if (ispipe) { |
1831 | if (core_limit == 0) { | 1861 | if (cprm.limit == 0) { |
1832 | /* | 1862 | /* |
1833 | * Normally core limits are irrelevant to pipes, since | 1863 | * Normally core limits are irrelevant to pipes, since |
1834 | * we're not writing to the file system, but we use | 1864 | * we're not writing to the file system, but we use |
1835 | * core_limit of 0 here as a speacial value. Any | 1865 | * cprm.limit of 0 here as a speacial value. Any |
1836 | * non-zero limit gets set to RLIM_INFINITY below, but | 1866 | * non-zero limit gets set to RLIM_INFINITY below, but |
1837 | * a limit of 0 skips the dump. This is a consistent | 1867 | * a limit of 0 skips the dump. This is a consistent |
1838 | * way to catch recursive crashes. We can still crash | 1868 | * way to catch recursive crashes. We can still crash |
@@ -1865,25 +1895,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1865 | goto fail_dropcount; | 1895 | goto fail_dropcount; |
1866 | } | 1896 | } |
1867 | 1897 | ||
1868 | core_limit = RLIM_INFINITY; | 1898 | cprm.limit = RLIM_INFINITY; |
1869 | 1899 | ||
1870 | /* SIGPIPE can happen, but it's just never processed */ | 1900 | /* SIGPIPE can happen, but it's just never processed */ |
1871 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, | 1901 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, |
1872 | &file)) { | 1902 | &cprm.file)) { |
1873 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1903 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1874 | corename); | 1904 | corename); |
1875 | goto fail_dropcount; | 1905 | goto fail_dropcount; |
1876 | } | 1906 | } |
1877 | } else | 1907 | } else |
1878 | file = filp_open(corename, | 1908 | cprm.file = filp_open(corename, |
1879 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 1909 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1880 | 0600); | 1910 | 0600); |
1881 | if (IS_ERR(file)) | 1911 | if (IS_ERR(cprm.file)) |
1882 | goto fail_dropcount; | 1912 | goto fail_dropcount; |
1883 | inode = file->f_path.dentry->d_inode; | 1913 | inode = cprm.file->f_path.dentry->d_inode; |
1884 | if (inode->i_nlink > 1) | 1914 | if (inode->i_nlink > 1) |
1885 | goto close_fail; /* multiple links - don't dump */ | 1915 | goto close_fail; /* multiple links - don't dump */ |
1886 | if (!ispipe && d_unhashed(file->f_path.dentry)) | 1916 | if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) |
1887 | goto close_fail; | 1917 | goto close_fail; |
1888 | 1918 | ||
1889 | /* 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., |
@@ -1896,21 +1926,22 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1896 | */ | 1926 | */ |
1897 | if (inode->i_uid != current_fsuid()) | 1927 | if (inode->i_uid != current_fsuid()) |
1898 | goto close_fail; | 1928 | goto close_fail; |
1899 | if (!file->f_op) | 1929 | if (!cprm.file->f_op) |
1900 | goto close_fail; | 1930 | goto close_fail; |
1901 | if (!file->f_op->write) | 1931 | if (!cprm.file->f_op->write) |
1902 | goto close_fail; | 1932 | goto close_fail; |
1903 | 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) | ||
1904 | goto close_fail; | 1935 | goto close_fail; |
1905 | 1936 | ||
1906 | retval = binfmt->core_dump(signr, regs, file, core_limit); | 1937 | retval = binfmt->core_dump(&cprm); |
1907 | 1938 | ||
1908 | if (retval) | 1939 | if (retval) |
1909 | current->signal->group_exit_code |= 0x80; | 1940 | current->signal->group_exit_code |= 0x80; |
1910 | close_fail: | 1941 | close_fail: |
1911 | if (ispipe && core_pipe_limit) | 1942 | if (ispipe && core_pipe_limit) |
1912 | wait_for_dump_helpers(file); | 1943 | wait_for_dump_helpers(cprm.file); |
1913 | filp_close(file, NULL); | 1944 | filp_close(cprm.file, NULL); |
1914 | fail_dropcount: | 1945 | fail_dropcount: |
1915 | if (dump_count) | 1946 | if (dump_count) |
1916 | atomic_dec(&core_dump_count); | 1947 | atomic_dec(&core_dump_count); |