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>
This commit is contained in:
committed by
Linus Torvalds
parent
c713541125
commit
d5bf4c4f5f
39
fs/exec.c
39
fs/exec.c
@@ -1841,10 +1841,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
|
|||||||
struct cred *cred;
|
struct cred *cred;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
int ispipe = 0;
|
int ispipe;
|
||||||
char **helper_argv = NULL;
|
|
||||||
int helper_argc = 0;
|
|
||||||
int dump_count = 0;
|
|
||||||
static atomic_t core_dump_count = ATOMIC_INIT(0);
|
static atomic_t core_dump_count = ATOMIC_INIT(0);
|
||||||
struct coredump_params cprm = {
|
struct coredump_params cprm = {
|
||||||
.signr = signr,
|
.signr = signr,
|
||||||
@@ -1914,6 +1911,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
|
|||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
|
|
||||||
if (ispipe) {
|
if (ispipe) {
|
||||||
|
int dump_count;
|
||||||
|
char **helper_argv;
|
||||||
|
|
||||||
if (cprm.limit == 1) {
|
if (cprm.limit == 1) {
|
||||||
/*
|
/*
|
||||||
* Normally core limits are irrelevant to pipes, since
|
* Normally core limits are irrelevant to pipes, since
|
||||||
@@ -1935,6 +1935,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
|
|||||||
printk(KERN_WARNING "Aborting core\n");
|
printk(KERN_WARNING "Aborting core\n");
|
||||||
goto fail_unlock;
|
goto fail_unlock;
|
||||||
}
|
}
|
||||||
|
cprm.limit = RLIM_INFINITY;
|
||||||
|
|
||||||
dump_count = atomic_inc_return(&core_dump_count);
|
dump_count = atomic_inc_return(&core_dump_count);
|
||||||
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
|
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)
|
|||||||
goto fail_dropcount;
|
goto fail_dropcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
|
helper_argv = argv_split(GFP_KERNEL, corename+1, NULL);
|
||||||
if (!helper_argv) {
|
if (!helper_argv) {
|
||||||
printk(KERN_WARNING "%s failed to allocate memory\n",
|
printk(KERN_WARNING "%s failed to allocate memory\n",
|
||||||
__func__);
|
__func__);
|
||||||
goto fail_dropcount;
|
goto fail_dropcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
cprm.limit = RLIM_INFINITY;
|
retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
|
||||||
|
NULL, UMH_WAIT_EXEC, umh_pipe_setup,
|
||||||
/* SIGPIPE can happen, but it's just never processed */
|
NULL, &cprm);
|
||||||
cprm.file = NULL;
|
argv_free(helper_argv);
|
||||||
if (call_usermodehelper_fns(helper_argv[0], helper_argv, NULL,
|
if (retval) {
|
||||||
UMH_WAIT_EXEC, umh_pipe_setup,
|
|
||||||
NULL, &cprm)) {
|
|
||||||
if (cprm.file)
|
|
||||||
filp_close(cprm.file, NULL);
|
|
||||||
|
|
||||||
printk(KERN_INFO "Core dump to %s pipe failed\n",
|
printk(KERN_INFO "Core dump to %s pipe failed\n",
|
||||||
corename);
|
corename);
|
||||||
goto fail_dropcount;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
@@ -2003,17 +1999,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
|
|||||||
retval = binfmt->core_dump(&cprm);
|
retval = binfmt->core_dump(&cprm);
|
||||||
if (retval)
|
if (retval)
|
||||||
current->signal->group_exit_code |= 0x80;
|
current->signal->group_exit_code |= 0x80;
|
||||||
close_fail:
|
|
||||||
if (ispipe && core_pipe_limit)
|
if (ispipe && core_pipe_limit)
|
||||||
wait_for_dump_helpers(cprm.file);
|
wait_for_dump_helpers(cprm.file);
|
||||||
filp_close(cprm.file, NULL);
|
close_fail:
|
||||||
|
if (cprm.file)
|
||||||
|
filp_close(cprm.file, NULL);
|
||||||
fail_dropcount:
|
fail_dropcount:
|
||||||
if (dump_count)
|
if (ispipe)
|
||||||
atomic_dec(&core_dump_count);
|
atomic_dec(&core_dump_count);
|
||||||
fail_unlock:
|
fail_unlock:
|
||||||
if (helper_argv)
|
|
||||||
argv_free(helper_argv);
|
|
||||||
|
|
||||||
revert_creds(old_cred);
|
revert_creds(old_cred);
|
||||||
put_cred(cred);
|
put_cred(cred);
|
||||||
coredump_finish(mm);
|
coredump_finish(mm);
|
||||||
|
Reference in New Issue
Block a user