sharkcz / rpms / kernel

Forked from rpms/kernel 6 years ago
Clone
Jesse Keating 3494df0
diff -up linux-2.6.32.noarch/fs/exec.c.orig linux-2.6.32.noarch/fs/exec.c
Jesse Keating 3494df0
--- linux-2.6.32.noarch/fs/exec.c.orig	2010-02-05 06:57:45.000000000 -0500
Jesse Keating 3494df0
+++ linux-2.6.32.noarch/fs/exec.c	2010-02-05 06:57:31.000000000 -0500
Jesse Keating 3494df0
@@ -1762,6 +1762,50 @@ static void wait_for_dump_helpers(struct
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 
Jesse Keating 3494df0
+/*
Jesse Keating 3494df0
+ * uhm_pipe_setup
Jesse Keating 3494df0
+ * helper function to customize the process used
Jesse Keating 3494df0
+ * to collect the core in userspace.  Specifically
Jesse Keating 3494df0
+ * it sets up a pipe and installs it as fd 0 (stdin)
Jesse Keating 3494df0
+ * for the process.  Returns 0 on success, or
Jesse Keating 3494df0
+ * PTR_ERR on failure.
Jesse Keating 3494df0
+ * Note that it also sets the core limit to 1.  This
Jesse Keating 3494df0
+ * is a special value that we use to trap recursive
Jesse Keating 3494df0
+ * core dumps
Jesse Keating 3494df0
+ */
Jesse Keating 3494df0
+static int umh_pipe_setup(struct subprocess_info *info)
Jesse Keating 3494df0
+{
Jesse Keating 3494df0
+	struct file *rp, *wp;
Jesse Keating 3494df0
+	struct fdtable *fdt;
Jesse Keating 3494df0
+	struct coredump_params *cp = (struct coredump_params *)info->data;
Jesse Keating 3494df0
+	struct files_struct *cf = current->files;
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	wp = create_write_pipe(0);
Jesse Keating 3494df0
+	if (IS_ERR(wp))
Jesse Keating 3494df0
+		return PTR_ERR(wp);
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	rp = create_read_pipe(wp, 0);
Jesse Keating 3494df0
+	if (IS_ERR(rp)) {
Jesse Keating 3494df0
+		free_write_pipe(wp);
Jesse Keating 3494df0
+		return PTR_ERR(rp);
Jesse Keating 3494df0
+	}
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	cp->file = wp;
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	sys_close(0);
Jesse Keating 3494df0
+	fd_install(0, rp);
Jesse Keating 3494df0
+	spin_lock(&cf->file_lock);
Jesse Keating 3494df0
+	fdt = files_fdtable(cf);
Jesse Keating 3494df0
+	FD_SET(0, fdt->open_fds);
Jesse Keating 3494df0
+	FD_CLR(0, fdt->close_on_exec);
Jesse Keating 3494df0
+	spin_unlock(&cf->file_lock);
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	/* and disallow core files too */
Jesse Keating 3494df0
+	current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+	return 0;
Jesse Keating 3494df0
+}
Jesse Keating 3494df0
+
Jesse Keating 3494df0
 void do_coredump(long signr, int exit_code, struct pt_regs *regs)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
 	struct core_state core_state;
Jesse Keating 3494df0
@@ -1842,15 +1886,15 @@ void do_coredump(long signr, int exit_co
Jesse Keating 3494df0
 		goto fail_unlock;
Jesse Keating 3494df0
 
Jesse Keating 3494df0
  	if (ispipe) {
Jesse Keating 3494df0
-		if (cprm.limit == 0) {
Jesse Keating 3494df0
+		if (cprm.limit == 1) {
Jesse Keating 3494df0
 			/*
Jesse Keating 3494df0
 			 * Normally core limits are irrelevant to pipes, since
Jesse Keating 3494df0
 			 * we're not writing to the file system, but we use
Jesse Keating 3494df0
-			 * cprm.limit of 0 here as a speacial value. Any
Jesse Keating 3494df0
-			 * non-zero limit gets set to RLIM_INFINITY below, but
Jesse Keating 3494df0
+			 * cprm.limit of 1 here as a speacial value. Any
Jesse Keating 3494df0
+			 * non-1 limit gets set to RLIM_INFINITY below, but
Jesse Keating 3494df0
 			 * a limit of 0 skips the dump.  This is a consistent
Jesse Keating 3494df0
 			 * way to catch recursive crashes.  We can still crash
Jesse Keating 3494df0
-			 * if the core_pattern binary sets RLIM_CORE =  !0
Jesse Keating 3494df0
+			 * if the core_pattern binary sets RLIM_CORE =  !1
Jesse Keating 3494df0
 			 * but it runs as root, and can do lots of stupid things
Jesse Keating 3494df0
 			 * Note that we use task_tgid_vnr here to grab the pid
Jesse Keating 3494df0
 			 * of the process group leader.  That way we get the
Jesse Keating 3494df0
@@ -1858,7 +1902,7 @@ void do_coredump(long signr, int exit_co
Jesse Keating 3494df0
 			 * core_pattern process dies.
Jesse Keating 3494df0
 			 */
Jesse Keating 3494df0
 			printk(KERN_WARNING
Jesse Keating 3494df0
-				"Process %d(%s) has RLIMIT_CORE set to 0\n",
Jesse Keating 3494df0
+				"Process %d(%s) has RLIMIT_CORE set to 1\n",
Jesse Keating 3494df0
 				task_tgid_vnr(current), current->comm);
Jesse Keating 3494df0
 			printk(KERN_WARNING "Aborting core\n");
Jesse Keating 3494df0
 			goto fail_unlock;
Jesse Keating 3494df0
@@ -1882,8 +1926,13 @@ void do_coredump(long signr, int exit_co
Jesse Keating 3494df0
 		cprm.limit = RLIM_INFINITY;
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 		/* SIGPIPE can happen, but it's just never processed */
Jesse Keating 3494df0
-		if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL,
Jesse Keating 3494df0
-				&cprm.file)) {
Jesse Keating 3494df0
+		cprm.file = NULL;
Jesse Keating 3494df0
+		if (call_usermodehelper_fns(helper_argv[0], helper_argv, NULL,
Jesse Keating 3494df0
+					    UMH_WAIT_EXEC, umh_pipe_setup,
Jesse Keating 3494df0
+					    NULL, &cprm)) {
Jesse Keating 3494df0
+			if (cprm.file)
Jesse Keating 3494df0
+				filp_close(cprm.file, NULL);
Jesse Keating 3494df0
+
Jesse Keating 3494df0
  			printk(KERN_INFO "Core dump to %s pipe failed\n",
Jesse Keating 3494df0
 			       corename);
Jesse Keating 3494df0
 			goto fail_dropcount;
Jesse Keating 3494df0
diff -up linux-2.6.32.noarch/include/linux/kmod.h.orig linux-2.6.32.noarch/include/linux/kmod.h
Jesse Keating 3494df0
--- linux-2.6.32.noarch/include/linux/kmod.h.orig	2010-02-05 06:57:45.000000000 -0500
Jesse Keating 3494df0
+++ linux-2.6.32.noarch/include/linux/kmod.h	2010-02-05 06:57:31.000000000 -0500
Jesse Keating 3494df0
@@ -23,6 +23,7 @@
Jesse Keating 3494df0
 #include <linux/stddef.h>
Jesse Keating 3494df0
 #include <linux/errno.h>
Jesse Keating 3494df0
 #include <linux/compiler.h>
Jesse Keating 3494df0
+#include <linux/workqueue.h>
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 #define KMOD_PATH_LEN 256
Jesse Keating 3494df0
 
Jesse Keating 3494df0
@@ -44,7 +45,26 @@ static inline int request_module_nowait(
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 struct key;
Jesse Keating 3494df0
 struct file;
Jesse Keating 3494df0
-struct subprocess_info;
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+enum umh_wait {
Jesse Keating 3494df0
+	UMH_NO_WAIT = -1,	/* don't wait at all */
Jesse Keating 3494df0
+	UMH_WAIT_EXEC = 0,	/* wait for the exec, but not the process */
Jesse Keating 3494df0
+	UMH_WAIT_PROC = 1,	/* wait for the process to complete */
Jesse Keating 3494df0
+};
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+struct subprocess_info {
Jesse Keating 3494df0
+	struct work_struct work;
Jesse Keating 3494df0
+	struct completion *complete;
Jesse Keating 3494df0
+	struct cred *cred;
Jesse Keating 3494df0
+	char *path;
Jesse Keating 3494df0
+	char **argv;
Jesse Keating 3494df0
+	char **envp;
Jesse Keating 3494df0
+	enum umh_wait wait;
Jesse Keating 3494df0
+	int retval;
Jesse Keating 3494df0
+	int (*init)(struct subprocess_info *info);
Jesse Keating 3494df0
+	void (*cleanup)(struct subprocess_info *info);
Jesse Keating 3494df0
+	void *data;
Jesse Keating 3494df0
+};
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 /* Allocate a subprocess_info structure */
Jesse Keating 3494df0
 struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
Jesse Keating 3494df0
@@ -55,14 +75,10 @@ void call_usermodehelper_setkeys(struct 
Jesse Keating 3494df0
 				 struct key *session_keyring);
Jesse Keating 3494df0
 int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
Jesse Keating 3494df0
 				  struct file **filp);
Jesse Keating 3494df0
-void call_usermodehelper_setcleanup(struct subprocess_info *info,
Jesse Keating 3494df0
-				    void (*cleanup)(char **argv, char **envp));
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-enum umh_wait {
Jesse Keating 3494df0
-	UMH_NO_WAIT = -1,	/* don't wait at all */
Jesse Keating 3494df0
-	UMH_WAIT_EXEC = 0,	/* wait for the exec, but not the process */
Jesse Keating 3494df0
-	UMH_WAIT_PROC = 1,	/* wait for the process to complete */
Jesse Keating 3494df0
-};
Jesse Keating 3494df0
+void call_usermodehelper_setfns(struct subprocess_info *info,
Jesse Keating 3494df0
+		    int (*init)(struct subprocess_info *info),
Jesse Keating 3494df0
+		    void (*cleanup)(struct subprocess_info *info),
Jesse Keating 3494df0
+		    void *data);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 /* Actually execute the sub-process */
Jesse Keating 3494df0
 int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
Jesse Keating 3494df0
@@ -72,7 +88,10 @@ int call_usermodehelper_exec(struct subp
Jesse Keating 3494df0
 void call_usermodehelper_freeinfo(struct subprocess_info *info);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 static inline int
Jesse Keating 3494df0
-call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
Jesse Keating 3494df0
+call_usermodehelper_fns(char *path, char **argv, char **envp,
Jesse Keating 3494df0
+			enum umh_wait wait,
Jesse Keating 3494df0
+			int (*init)(struct subprocess_info *info),
Jesse Keating 3494df0
+			void (*cleanup)(struct subprocess_info *), void *data)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
 	struct subprocess_info *info;
Jesse Keating 3494df0
 	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
Jesse Keating 3494df0
@@ -80,10 +99,18 @@ call_usermodehelper(char *path, char **a
Jesse Keating 3494df0
 	info = call_usermodehelper_setup(path, argv, envp, gfp_mask);
Jesse Keating 3494df0
 	if (info == NULL)
Jesse Keating 3494df0
 		return -ENOMEM;
Jesse Keating 3494df0
+	call_usermodehelper_setfns(info, init, cleanup, data);
Jesse Keating 3494df0
 	return call_usermodehelper_exec(info, wait);
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 static inline int
Jesse Keating 3494df0
+call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
Jesse Keating 3494df0
+{
Jesse Keating 3494df0
+	return call_usermodehelper_fns(path, argv, envp,
Jesse Keating 3494df0
+				       wait, NULL, NULL, NULL);
Jesse Keating 3494df0
+}
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+static inline int
Jesse Keating 3494df0
 call_usermodehelper_keys(char *path, char **argv, char **envp,
Jesse Keating 3494df0
 			 struct key *session_keyring, enum umh_wait wait)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
@@ -100,10 +127,6 @@ call_usermodehelper_keys(char *path, cha
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 extern void usermodehelper_init(void);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-struct file;
Jesse Keating 3494df0
-extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
Jesse Keating 3494df0
-				    struct file **filp);
Jesse Keating 3494df0
-
Jesse Keating 3494df0
 extern int usermodehelper_disable(void);
Jesse Keating 3494df0
 extern void usermodehelper_enable(void);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
diff -up linux-2.6.32.noarch/kernel/kmod.c.orig linux-2.6.32.noarch/kernel/kmod.c
Jesse Keating 3494df0
--- linux-2.6.32.noarch/kernel/kmod.c.orig	2010-02-05 06:57:45.000000000 -0500
Jesse Keating 3494df0
+++ linux-2.6.32.noarch/kernel/kmod.c	2010-02-05 06:57:31.000000000 -0500
Jesse Keating 3494df0
@@ -124,19 +124,6 @@ int __request_module(bool wait, const ch
Jesse Keating 3494df0
 EXPORT_SYMBOL(__request_module);
Jesse Keating 3494df0
 #endif /* CONFIG_MODULES */
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-struct subprocess_info {
Jesse Keating 3494df0
-	struct work_struct work;
Jesse Keating 3494df0
-	struct completion *complete;
Jesse Keating 3494df0
-	struct cred *cred;
Jesse Keating 3494df0
-	char *path;
Jesse Keating 3494df0
-	char **argv;
Jesse Keating 3494df0
-	char **envp;
Jesse Keating 3494df0
-	enum umh_wait wait;
Jesse Keating 3494df0
-	int retval;
Jesse Keating 3494df0
-	struct file *stdin;
Jesse Keating 3494df0
-	void (*cleanup)(char **argv, char **envp);
Jesse Keating 3494df0
-};
Jesse Keating 3494df0
-
Jesse Keating 3494df0
 /*
Jesse Keating 3494df0
  * This is the task which runs the usermode application
Jesse Keating 3494df0
  */
Jesse Keating 3494df0
@@ -158,26 +145,15 @@ static int ____call_usermodehelper(void 
Jesse Keating 3494df0
 	commit_creds(sub_info->cred);
Jesse Keating 3494df0
 	sub_info->cred = NULL;
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-	/* Install input pipe when needed */
Jesse Keating 3494df0
-	if (sub_info->stdin) {
Jesse Keating 3494df0
-		struct files_struct *f = current->files;
Jesse Keating 3494df0
-		struct fdtable *fdt;
Jesse Keating 3494df0
-		/* no races because files should be private here */
Jesse Keating 3494df0
-		sys_close(0);
Jesse Keating 3494df0
-		fd_install(0, sub_info->stdin);
Jesse Keating 3494df0
-		spin_lock(&f->file_lock);
Jesse Keating 3494df0
-		fdt = files_fdtable(f);
Jesse Keating 3494df0
-		FD_SET(0, fdt->open_fds);
Jesse Keating 3494df0
-		FD_CLR(0, fdt->close_on_exec);
Jesse Keating 3494df0
-		spin_unlock(&f->file_lock);
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-		/* and disallow core files too */
Jesse Keating 3494df0
-		current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
Jesse Keating 3494df0
-	}
Jesse Keating 3494df0
-
Jesse Keating 3494df0
 	/* We can run anywhere, unlike our parent keventd(). */
Jesse Keating 3494df0
 	set_cpus_allowed_ptr(current, cpu_all_mask);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
+	if (sub_info->init) {
Jesse Keating 3494df0
+		retval = sub_info->init(sub_info);
Jesse Keating 3494df0
+		if (retval)
Jesse Keating 3494df0
+			goto fail;
Jesse Keating 3494df0
+	}
Jesse Keating 3494df0
+
Jesse Keating 3494df0
 	/*
Jesse Keating 3494df0
 	 * Our parent is keventd, which runs with elevated scheduling priority.
Jesse Keating 3494df0
 	 * Avoid propagating that into the userspace child.
Jesse Keating 3494df0
@@ -187,6 +163,7 @@ static int ____call_usermodehelper(void 
Jesse Keating 3494df0
 	retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 	/* Exec failed? */
Jesse Keating 3494df0
+fail:
Jesse Keating 3494df0
 	sub_info->retval = retval;
Jesse Keating 3494df0
 	do_exit(0);
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
@@ -194,7 +171,7 @@ static int ____call_usermodehelper(void 
Jesse Keating 3494df0
 void call_usermodehelper_freeinfo(struct subprocess_info *info)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
 	if (info->cleanup)
Jesse Keating 3494df0
-		(*info->cleanup)(info->argv, info->envp);
Jesse Keating 3494df0
+		(*info->cleanup)(info);
Jesse Keating 3494df0
 	if (info->cred)
Jesse Keating 3494df0
 		put_cred(info->cred);
Jesse Keating 3494df0
 	kfree(info);
Jesse Keating 3494df0
@@ -406,50 +383,31 @@ void call_usermodehelper_setkeys(struct 
Jesse Keating 3494df0
 EXPORT_SYMBOL(call_usermodehelper_setkeys);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 /**
Jesse Keating 3494df0
- * call_usermodehelper_setcleanup - set a cleanup function
Jesse Keating 3494df0
+ * call_usermodehelper_setfns - set a cleanup/init function
Jesse Keating 3494df0
  * @info: a subprocess_info returned by call_usermodehelper_setup
Jesse Keating 3494df0
  * @cleanup: a cleanup function
Jesse Keating 3494df0
+ * @init: an init function
Jesse Keating 3494df0
+ * @data: arbitrary context sensitive data
Jesse Keating 3494df0
  *
Jesse Keating 3494df0
- * The cleanup function is just befor ethe subprocess_info is about to
Jesse Keating 3494df0
+ * The init function is used to customize the helper process prior to
Jesse Keating 3494df0
+ * exec.  A non-zero return code causes the process to error out, exit,
Jesse Keating 3494df0
+ * and return the failure to the calling process
Jesse Keating 3494df0
+ *
Jesse Keating 3494df0
+ * The cleanup function is just before ethe subprocess_info is about to
Jesse Keating 3494df0
  * be freed.  This can be used for freeing the argv and envp.  The
Jesse Keating 3494df0
  * Function must be runnable in either a process context or the
Jesse Keating 3494df0
  * context in which call_usermodehelper_exec is called.
Jesse Keating 3494df0
  */
Jesse Keating 3494df0
-void call_usermodehelper_setcleanup(struct subprocess_info *info,
Jesse Keating 3494df0
-				    void (*cleanup)(char **argv, char **envp))
Jesse Keating 3494df0
+void call_usermodehelper_setfns(struct subprocess_info *info,
Jesse Keating 3494df0
+		    int (*init)(struct subprocess_info *info),
Jesse Keating 3494df0
+		    void (*cleanup)(struct subprocess_info *info),
Jesse Keating 3494df0
+		    void *data)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
 	info->cleanup = cleanup;
Jesse Keating 3494df0
+	info->init = init;
Jesse Keating 3494df0
+	info->data = data;
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
-EXPORT_SYMBOL(call_usermodehelper_setcleanup);
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-/**
Jesse Keating 3494df0
- * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
Jesse Keating 3494df0
- * @sub_info: a subprocess_info returned by call_usermodehelper_setup
Jesse Keating 3494df0
- * @filp: set to the write-end of a pipe
Jesse Keating 3494df0
- *
Jesse Keating 3494df0
- * This constructs a pipe, and sets the read end to be the stdin of the
Jesse Keating 3494df0
- * subprocess, and returns the write-end in *@filp.
Jesse Keating 3494df0
- */
Jesse Keating 3494df0
-int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
Jesse Keating 3494df0
-				  struct file **filp)
Jesse Keating 3494df0
-{
Jesse Keating 3494df0
-	struct file *f;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	f = create_write_pipe(0);
Jesse Keating 3494df0
-	if (IS_ERR(f))
Jesse Keating 3494df0
-		return PTR_ERR(f);
Jesse Keating 3494df0
-	*filp = f;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	f = create_read_pipe(f, 0);
Jesse Keating 3494df0
-	if (IS_ERR(f)) {
Jesse Keating 3494df0
-		free_write_pipe(*filp);
Jesse Keating 3494df0
-		return PTR_ERR(f);
Jesse Keating 3494df0
-	}
Jesse Keating 3494df0
-	sub_info->stdin = f;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	return 0;
Jesse Keating 3494df0
-}
Jesse Keating 3494df0
-EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
Jesse Keating 3494df0
+EXPORT_SYMBOL(call_usermodehelper_setfns);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 /**
Jesse Keating 3494df0
  * call_usermodehelper_exec - start a usermode application
Jesse Keating 3494df0
@@ -498,41 +456,6 @@ unlock:
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
 EXPORT_SYMBOL(call_usermodehelper_exec);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-/**
Jesse Keating 3494df0
- * call_usermodehelper_pipe - call a usermode helper process with a pipe stdin
Jesse Keating 3494df0
- * @path: path to usermode executable
Jesse Keating 3494df0
- * @argv: arg vector for process
Jesse Keating 3494df0
- * @envp: environment for process
Jesse Keating 3494df0
- * @filp: set to the write-end of a pipe
Jesse Keating 3494df0
- *
Jesse Keating 3494df0
- * This is a simple wrapper which executes a usermode-helper function
Jesse Keating 3494df0
- * with a pipe as stdin.  It is implemented entirely in terms of
Jesse Keating 3494df0
- * lower-level call_usermodehelper_* functions.
Jesse Keating 3494df0
- */
Jesse Keating 3494df0
-int call_usermodehelper_pipe(char *path, char **argv, char **envp,
Jesse Keating 3494df0
-			     struct file **filp)
Jesse Keating 3494df0
-{
Jesse Keating 3494df0
-	struct subprocess_info *sub_info;
Jesse Keating 3494df0
-	int ret;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	sub_info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL);
Jesse Keating 3494df0
-	if (sub_info == NULL)
Jesse Keating 3494df0
-		return -ENOMEM;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	ret = call_usermodehelper_stdinpipe(sub_info, filp);
Jesse Keating 3494df0
-	if (ret < 0) {
Jesse Keating 3494df0
-		call_usermodehelper_freeinfo(sub_info);
Jesse Keating 3494df0
-		return ret;
Jesse Keating 3494df0
-	}
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	ret = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
Jesse Keating 3494df0
-	if (ret < 0)	/* Failed to execute helper, close pipe */
Jesse Keating 3494df0
-		filp_close(*filp, NULL);
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	return ret;
Jesse Keating 3494df0
-}
Jesse Keating 3494df0
-EXPORT_SYMBOL(call_usermodehelper_pipe);
Jesse Keating 3494df0
-
Jesse Keating 3494df0
 void __init usermodehelper_init(void)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
 	khelper_wq = create_singlethread_workqueue("khelper");
Jesse Keating 3494df0
diff -up linux-2.6.32.noarch/kernel/sys.c.orig linux-2.6.32.noarch/kernel/sys.c
Jesse Keating 3494df0
--- linux-2.6.32.noarch/kernel/sys.c.orig	2010-02-05 06:57:45.000000000 -0500
Jesse Keating 3494df0
+++ linux-2.6.32.noarch/kernel/sys.c	2010-02-05 06:48:30.000000000 -0500
Jesse Keating 3494df0
@@ -1599,9 +1599,9 @@ SYSCALL_DEFINE3(getcpu, unsigned __user 
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-static void argv_cleanup(char **argv, char **envp)
Jesse Keating 3494df0
+static void argv_cleanup(struct subprocess_info *info)
Jesse Keating 3494df0
 {
Jesse Keating 3494df0
-	argv_free(argv);
Jesse Keating 3494df0
+	argv_free(info->argv);
Jesse Keating 3494df0
 }
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 /**
Jesse Keating 3494df0
@@ -1635,7 +1635,7 @@ int orderly_poweroff(bool force)
Jesse Keating 3494df0
 		goto out;
Jesse Keating 3494df0
 	}
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-	call_usermodehelper_setcleanup(info, argv_cleanup);
Jesse Keating 3494df0
+	call_usermodehelper_setfns(info, NULL, argv_cleanup, NULL);
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 	ret = call_usermodehelper_exec(info, UMH_NO_WAIT);
Jesse Keating 3494df0