From 74aadce986052f20088c2678f589ea0e8d3a4b59 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 16 Oct 2007 23:26:35 -0700 Subject: core_pattern: allow passing of arguments to user mode helper when core_pattern is a pipe A rewrite of my previous post for this enhancement. It uses jeremy's split_argv/free_argv library functions to translate core_pattern into an argv array to be passed to the user mode helper process. It also adds a translation to format_corename such that the origional value of RLIMIT_CORE can be passed to userspace as an argument. Signed-off-by: Neil Horman Cc: Cc: Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'fs/exec.c') diff --git a/fs/exec.c b/fs/exec.c index 86c455447bc8..6450157062ea 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1514,6 +1515,14 @@ static int format_corename(char *corename, const char *pattern, long signr) goto out; out_ptr += rc; break; + /* core limit size */ + case 'c': + rc = snprintf(out_ptr, out_end - out_ptr, + "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur); + if (rc > out_end - out_ptr) + goto out; + out_ptr += rc; + break; default: break; } @@ -1698,6 +1707,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) int flag = 0; int ispipe = 0; unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; + char **helper_argv = NULL; + int helper_argc = 0; + char *delimit; audit_core_dumps(signr); @@ -1746,14 +1758,18 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) * at which point file size limits and permissions will be imposed * as it does with any other process */ - if ((!ispipe) && - (core_limit < binfmt->min_coredump)) + if ((!ispipe) && (core_limit < binfmt->min_coredump)) goto fail_unlock; if (ispipe) { core_limit = RLIM_INFINITY; + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); + /* Terminate the string before the first option */ + delimit = strchr(corename, ' '); + if (delimit) + *delimit = '\0'; /* SIGPIPE can happen, but it's just never processed */ - if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { + if(call_usermodehelper_pipe(corename+1, helper_argv, NULL, &file)) { printk(KERN_INFO "Core dump to %s pipe failed\n", corename); goto fail_unlock; @@ -1788,6 +1804,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) close_fail: filp_close(file, NULL); fail_unlock: + if (helper_argv) + argv_free(helper_argv); + current->fsuid = fsuid; complete_all(&mm->core_done); fail: -- cgit v1.2.3