aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2010-05-26 17:42:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:44 -0400
commit898b374af6f71041bd3bceebe257e564f3f1d458 (patch)
treeb1be6fd3cca69becfc75787eab906338f363d3cd /fs
parenta06a4dc3a08201ff6a8a958f935b3cbf7744115f (diff)
exec: replace call_usermodehelper_pipe with use of umh init function and resolve limit
The first patch in this series introduced an init function to the call_usermodehelper api so that processes could be customized by caller. This patch takes advantage of that fact, by customizing the helper in do_coredump to create the pipe and set its core limit to one (for our recusrsion check). This lets us clean up the previous uglyness in the usermodehelper internals and factor call_usermodehelper out entirely. While I'm at it, we can also modify the helper setup to look for a core limit value of 1 rather than zero for our recursion check Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 9badbc0bfb1d..63f459cf20df 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1787,6 +1787,50 @@ static void wait_for_dump_helpers(struct file *file)
1787} 1787}
1788 1788
1789 1789
1790/*
1791 * uhm_pipe_setup
1792 * helper function to customize the process used
1793 * to collect the core in userspace. Specifically
1794 * it sets up a pipe and installs it as fd 0 (stdin)
1795 * for the process. Returns 0 on success, or
1796 * PTR_ERR on failure.
1797 * Note that it also sets the core limit to 1. This
1798 * is a special value that we use to trap recursive
1799 * core dumps
1800 */
1801static int umh_pipe_setup(struct subprocess_info *info)
1802{
1803 struct file *rp, *wp;
1804 struct fdtable *fdt;
1805 struct coredump_params *cp = (struct coredump_params *)info->data;
1806 struct files_struct *cf = current->files;
1807
1808 wp = create_write_pipe(0);
1809 if (IS_ERR(wp))
1810 return PTR_ERR(wp);
1811
1812 rp = create_read_pipe(wp, 0);
1813 if (IS_ERR(rp)) {
1814 free_write_pipe(wp);
1815 return PTR_ERR(rp);
1816 }
1817
1818 cp->file = wp;
1819
1820 sys_close(0);
1821 fd_install(0, rp);
1822 spin_lock(&cf->file_lock);
1823 fdt = files_fdtable(cf);
1824 FD_SET(0, fdt->open_fds);
1825 FD_CLR(0, fdt->close_on_exec);
1826 spin_unlock(&cf->file_lock);
1827
1828 /* and disallow core files too */
1829 current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
1830
1831 return 0;
1832}
1833
1790void do_coredump(long signr, int exit_code, struct pt_regs *regs) 1834void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1791{ 1835{
1792 struct core_state core_state; 1836 struct core_state core_state;
@@ -1874,15 +1918,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1874 goto fail_unlock; 1918 goto fail_unlock;
1875 1919
1876 if (ispipe) { 1920 if (ispipe) {
1877 if (cprm.limit == 0) { 1921 if (cprm.limit == 1) {
1878 /* 1922 /*
1879 * Normally core limits are irrelevant to pipes, since 1923 * Normally core limits are irrelevant to pipes, since
1880 * we're not writing to the file system, but we use 1924 * we're not writing to the file system, but we use
1881 * cprm.limit of 0 here as a speacial value. Any 1925 * cprm.limit of 1 here as a speacial value. Any
1882 * non-zero limit gets set to RLIM_INFINITY below, but 1926 * non-1 limit gets set to RLIM_INFINITY below, but
1883 * a limit of 0 skips the dump. This is a consistent 1927 * a limit of 0 skips the dump. This is a consistent
1884 * way to catch recursive crashes. We can still crash 1928 * way to catch recursive crashes. We can still crash
1885 * if the core_pattern binary sets RLIM_CORE = !0 1929 * if the core_pattern binary sets RLIM_CORE = !1
1886 * but it runs as root, and can do lots of stupid things 1930 * but it runs as root, and can do lots of stupid things
1887 * Note that we use task_tgid_vnr here to grab the pid 1931 * Note that we use task_tgid_vnr here to grab the pid
1888 * of the process group leader. That way we get the 1932 * of the process group leader. That way we get the
@@ -1890,7 +1934,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1890 * core_pattern process dies. 1934 * core_pattern process dies.
1891 */ 1935 */
1892 printk(KERN_WARNING 1936 printk(KERN_WARNING
1893 "Process %d(%s) has RLIMIT_CORE set to 0\n", 1937 "Process %d(%s) has RLIMIT_CORE set to 1\n",
1894 task_tgid_vnr(current), current->comm); 1938 task_tgid_vnr(current), current->comm);
1895 printk(KERN_WARNING "Aborting core\n"); 1939 printk(KERN_WARNING "Aborting core\n");
1896 goto fail_unlock; 1940 goto fail_unlock;
@@ -1914,8 +1958,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1914 cprm.limit = RLIM_INFINITY; 1958 cprm.limit = RLIM_INFINITY;
1915 1959
1916 /* SIGPIPE can happen, but it's just never processed */ 1960 /* SIGPIPE can happen, but it's just never processed */
1917 if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, 1961 cprm.file = NULL;
1918 &cprm.file)) { 1962 if (call_usermodehelper_fns(helper_argv[0], helper_argv, NULL,
1963 UMH_WAIT_EXEC, umh_pipe_setup,
1964 NULL, &cprm)) {
1965 if (cprm.file)
1966 filp_close(cprm.file, NULL);
1967
1919 printk(KERN_INFO "Core dump to %s pipe failed\n", 1968 printk(KERN_INFO "Core dump to %s pipe failed\n",
1920 corename); 1969 corename);
1921 goto fail_dropcount; 1970 goto fail_dropcount;