diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 49 |
1 files changed, 32 insertions, 17 deletions
@@ -826,7 +826,9 @@ static int de_thread(struct task_struct *tsk) | |||
826 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); | 826 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); |
827 | transfer_pid(leader, tsk, PIDTYPE_PGID); | 827 | transfer_pid(leader, tsk, PIDTYPE_PGID); |
828 | transfer_pid(leader, tsk, PIDTYPE_SID); | 828 | transfer_pid(leader, tsk, PIDTYPE_SID); |
829 | |||
829 | list_replace_rcu(&leader->tasks, &tsk->tasks); | 830 | list_replace_rcu(&leader->tasks, &tsk->tasks); |
831 | list_replace_init(&leader->sibling, &tsk->sibling); | ||
830 | 832 | ||
831 | tsk->group_leader = tsk; | 833 | tsk->group_leader = tsk; |
832 | leader->group_leader = tsk; | 834 | leader->group_leader = tsk; |
@@ -923,6 +925,15 @@ char *get_task_comm(char *buf, struct task_struct *tsk) | |||
923 | void set_task_comm(struct task_struct *tsk, char *buf) | 925 | void set_task_comm(struct task_struct *tsk, char *buf) |
924 | { | 926 | { |
925 | task_lock(tsk); | 927 | task_lock(tsk); |
928 | |||
929 | /* | ||
930 | * Threads may access current->comm without holding | ||
931 | * the task lock, so write the string carefully. | ||
932 | * Readers without a lock may see incomplete new | ||
933 | * names but are safe from non-terminating string reads. | ||
934 | */ | ||
935 | memset(tsk->comm, 0, TASK_COMM_LEN); | ||
936 | wmb(); | ||
926 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); | 937 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); |
927 | task_unlock(tsk); | 938 | task_unlock(tsk); |
928 | perf_event_comm(tsk); | 939 | perf_event_comm(tsk); |
@@ -1752,17 +1763,20 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1752 | struct mm_struct *mm = current->mm; | 1763 | struct mm_struct *mm = current->mm; |
1753 | struct linux_binfmt * binfmt; | 1764 | struct linux_binfmt * binfmt; |
1754 | struct inode * inode; | 1765 | struct inode * inode; |
1755 | struct file * file; | ||
1756 | const struct cred *old_cred; | 1766 | const struct cred *old_cred; |
1757 | struct cred *cred; | 1767 | struct cred *cred; |
1758 | int retval = 0; | 1768 | int retval = 0; |
1759 | int flag = 0; | 1769 | int flag = 0; |
1760 | int ispipe = 0; | 1770 | int ispipe = 0; |
1761 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | ||
1762 | char **helper_argv = NULL; | 1771 | char **helper_argv = NULL; |
1763 | int helper_argc = 0; | 1772 | int helper_argc = 0; |
1764 | int dump_count = 0; | 1773 | int dump_count = 0; |
1765 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 1774 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
1775 | struct coredump_params cprm = { | ||
1776 | .signr = signr, | ||
1777 | .regs = regs, | ||
1778 | .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, | ||
1779 | }; | ||
1766 | 1780 | ||
1767 | audit_core_dumps(signr); | 1781 | audit_core_dumps(signr); |
1768 | 1782 | ||
@@ -1818,15 +1832,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1818 | ispipe = format_corename(corename, signr); | 1832 | ispipe = format_corename(corename, signr); |
1819 | unlock_kernel(); | 1833 | unlock_kernel(); |
1820 | 1834 | ||
1821 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) | 1835 | if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) |
1822 | goto fail_unlock; | 1836 | goto fail_unlock; |
1823 | 1837 | ||
1824 | if (ispipe) { | 1838 | if (ispipe) { |
1825 | if (core_limit == 0) { | 1839 | if (cprm.limit == 0) { |
1826 | /* | 1840 | /* |
1827 | * Normally core limits are irrelevant to pipes, since | 1841 | * Normally core limits are irrelevant to pipes, since |
1828 | * we're not writing to the file system, but we use | 1842 | * we're not writing to the file system, but we use |
1829 | * core_limit of 0 here as a speacial value. Any | 1843 | * cprm.limit of 0 here as a speacial value. Any |
1830 | * non-zero limit gets set to RLIM_INFINITY below, but | 1844 | * non-zero limit gets set to RLIM_INFINITY below, but |
1831 | * a limit of 0 skips the dump. This is a consistent | 1845 | * a limit of 0 skips the dump. This is a consistent |
1832 | * way to catch recursive crashes. We can still crash | 1846 | * way to catch recursive crashes. We can still crash |
@@ -1859,25 +1873,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1859 | goto fail_dropcount; | 1873 | goto fail_dropcount; |
1860 | } | 1874 | } |
1861 | 1875 | ||
1862 | core_limit = RLIM_INFINITY; | 1876 | cprm.limit = RLIM_INFINITY; |
1863 | 1877 | ||
1864 | /* SIGPIPE can happen, but it's just never processed */ | 1878 | /* SIGPIPE can happen, but it's just never processed */ |
1865 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, | 1879 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, |
1866 | &file)) { | 1880 | &cprm.file)) { |
1867 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1881 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1868 | corename); | 1882 | corename); |
1869 | goto fail_dropcount; | 1883 | goto fail_dropcount; |
1870 | } | 1884 | } |
1871 | } else | 1885 | } else |
1872 | file = filp_open(corename, | 1886 | cprm.file = filp_open(corename, |
1873 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 1887 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1874 | 0600); | 1888 | 0600); |
1875 | if (IS_ERR(file)) | 1889 | if (IS_ERR(cprm.file)) |
1876 | goto fail_dropcount; | 1890 | goto fail_dropcount; |
1877 | inode = file->f_path.dentry->d_inode; | 1891 | inode = cprm.file->f_path.dentry->d_inode; |
1878 | if (inode->i_nlink > 1) | 1892 | if (inode->i_nlink > 1) |
1879 | goto close_fail; /* multiple links - don't dump */ | 1893 | goto close_fail; /* multiple links - don't dump */ |
1880 | if (!ispipe && d_unhashed(file->f_path.dentry)) | 1894 | if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) |
1881 | goto close_fail; | 1895 | goto close_fail; |
1882 | 1896 | ||
1883 | /* AK: actually i see no reason to not allow this for named pipes etc., | 1897 | /* AK: actually i see no reason to not allow this for named pipes etc., |
@@ -1890,21 +1904,22 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1890 | */ | 1904 | */ |
1891 | if (inode->i_uid != current_fsuid()) | 1905 | if (inode->i_uid != current_fsuid()) |
1892 | goto close_fail; | 1906 | goto close_fail; |
1893 | if (!file->f_op) | 1907 | if (!cprm.file->f_op) |
1894 | goto close_fail; | 1908 | goto close_fail; |
1895 | if (!file->f_op->write) | 1909 | if (!cprm.file->f_op->write) |
1896 | goto close_fail; | 1910 | goto close_fail; |
1897 | if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) | 1911 | if (!ispipe && |
1912 | do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0) | ||
1898 | goto close_fail; | 1913 | goto close_fail; |
1899 | 1914 | ||
1900 | retval = binfmt->core_dump(signr, regs, file, core_limit); | 1915 | retval = binfmt->core_dump(&cprm); |
1901 | 1916 | ||
1902 | if (retval) | 1917 | if (retval) |
1903 | current->signal->group_exit_code |= 0x80; | 1918 | current->signal->group_exit_code |= 0x80; |
1904 | close_fail: | 1919 | close_fail: |
1905 | if (ispipe && core_pipe_limit) | 1920 | if (ispipe && core_pipe_limit) |
1906 | wait_for_dump_helpers(file); | 1921 | wait_for_dump_helpers(cprm.file); |
1907 | filp_close(file, NULL); | 1922 | filp_close(cprm.file, NULL); |
1908 | fail_dropcount: | 1923 | fail_dropcount: |
1909 | if (dump_count) | 1924 | if (dump_count) |
1910 | atomic_dec(&core_dump_count); | 1925 | atomic_dec(&core_dump_count); |