diff options
author | Oleg Nesterov <oleg@redhat.com> | 2010-05-26 17:43:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 12:12:45 -0400 |
commit | d5bf4c4f5f9dcc90b7e25dbb2f7c4436cf6e7ed0 (patch) | |
tree | 8c07402f685245fdf3397fac47bc7194f686066d | |
parent | c713541125002b8bc9e681af3b09118e771e2d8a (diff) |
coredump: cleanup "ispipe" code
- kill "int dump_count", argv_split(argcp) accepts argcp == NULL.
- move "int dump_count" under " if (ispipe)" branch, fail_dropcount
can check ispipe.
- move "char **helper_argv" as well, change the code to do argv_free()
right after call_usermodehelper_fns().
- If call_usermodehelper_fns() fails goto close_fail label instead
of closing the file by hand.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Roland McGrath <roland@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>
-rw-r--r-- | fs/exec.c | 39 |
1 files changed, 17 insertions, 22 deletions
@@ -1841,10 +1841,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1841 | struct cred *cred; | 1841 | struct cred *cred; |
1842 | int retval = 0; | 1842 | int retval = 0; |
1843 | int flag = 0; | 1843 | int flag = 0; |
1844 | int ispipe = 0; | 1844 | int ispipe; |
1845 | char **helper_argv = NULL; | ||
1846 | int helper_argc = 0; | ||
1847 | int dump_count = 0; | ||
1848 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 1845 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
1849 | struct coredump_params cprm = { | 1846 | struct coredump_params cprm = { |
1850 | .signr = signr, | 1847 | .signr = signr, |
@@ -1914,6 +1911,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1914 | unlock_kernel(); | 1911 | unlock_kernel(); |
1915 | 1912 | ||
1916 | if (ispipe) { | 1913 | if (ispipe) { |
1914 | int dump_count; | ||
1915 | char **helper_argv; | ||
1916 | |||
1917 | if (cprm.limit == 1) { | 1917 | if (cprm.limit == 1) { |
1918 | /* | 1918 | /* |
1919 | * Normally core limits are irrelevant to pipes, since | 1919 | * Normally core limits are irrelevant to pipes, since |
@@ -1935,6 +1935,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1935 | printk(KERN_WARNING "Aborting core\n"); | 1935 | printk(KERN_WARNING "Aborting core\n"); |
1936 | goto fail_unlock; | 1936 | goto fail_unlock; |
1937 | } | 1937 | } |
1938 | cprm.limit = RLIM_INFINITY; | ||
1938 | 1939 | ||
1939 | dump_count = atomic_inc_return(&core_dump_count); | 1940 | dump_count = atomic_inc_return(&core_dump_count); |
1940 | if (core_pipe_limit && (core_pipe_limit < dump_count)) { | 1941 | if (core_pipe_limit && (core_pipe_limit < dump_count)) { |
@@ -1944,26 +1945,21 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1944 | goto fail_dropcount; | 1945 | goto fail_dropcount; |
1945 | } | 1946 | } |
1946 | 1947 | ||
1947 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); | 1948 | helper_argv = argv_split(GFP_KERNEL, corename+1, NULL); |
1948 | if (!helper_argv) { | 1949 | if (!helper_argv) { |
1949 | printk(KERN_WARNING "%s failed to allocate memory\n", | 1950 | printk(KERN_WARNING "%s failed to allocate memory\n", |
1950 | __func__); | 1951 | __func__); |
1951 | goto fail_dropcount; | 1952 | goto fail_dropcount; |
1952 | } | 1953 | } |
1953 | 1954 | ||
1954 | cprm.limit = RLIM_INFINITY; | 1955 | retval = call_usermodehelper_fns(helper_argv[0], helper_argv, |
1955 | 1956 | NULL, UMH_WAIT_EXEC, umh_pipe_setup, | |
1956 | /* SIGPIPE can happen, but it's just never processed */ | 1957 | NULL, &cprm); |
1957 | cprm.file = NULL; | 1958 | argv_free(helper_argv); |
1958 | if (call_usermodehelper_fns(helper_argv[0], helper_argv, NULL, | 1959 | if (retval) { |
1959 | UMH_WAIT_EXEC, umh_pipe_setup, | ||
1960 | NULL, &cprm)) { | ||
1961 | if (cprm.file) | ||
1962 | filp_close(cprm.file, NULL); | ||
1963 | |||
1964 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1960 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1965 | corename); | 1961 | corename); |
1966 | goto fail_dropcount; | 1962 | goto close_fail; |
1967 | } | 1963 | } |
1968 | } else { | 1964 | } else { |
1969 | struct inode *inode; | 1965 | struct inode *inode; |
@@ -2003,17 +1999,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
2003 | retval = binfmt->core_dump(&cprm); | 1999 | retval = binfmt->core_dump(&cprm); |
2004 | if (retval) | 2000 | if (retval) |
2005 | current->signal->group_exit_code |= 0x80; | 2001 | current->signal->group_exit_code |= 0x80; |
2006 | close_fail: | 2002 | |
2007 | if (ispipe && core_pipe_limit) | 2003 | if (ispipe && core_pipe_limit) |
2008 | wait_for_dump_helpers(cprm.file); | 2004 | wait_for_dump_helpers(cprm.file); |
2009 | filp_close(cprm.file, NULL); | 2005 | close_fail: |
2006 | if (cprm.file) | ||
2007 | filp_close(cprm.file, NULL); | ||
2010 | fail_dropcount: | 2008 | fail_dropcount: |
2011 | if (dump_count) | 2009 | if (ispipe) |
2012 | atomic_dec(&core_dump_count); | 2010 | atomic_dec(&core_dump_count); |
2013 | fail_unlock: | 2011 | fail_unlock: |
2014 | if (helper_argv) | ||
2015 | argv_free(helper_argv); | ||
2016 | |||
2017 | revert_creds(old_cred); | 2012 | revert_creds(old_cred); |
2018 | put_cred(cred); | 2013 | put_cred(cred); |
2019 | coredump_finish(mm); | 2014 | coredump_finish(mm); |