All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Kent <raven@themaw.net>
To: Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: David Howells <dhowells@redhat.com>,
	Oleg Nesterov <onestero@redhat.com>,
	Trond Myklebust <trond.myklebust@primarydata.com>,
	"J. Bruce Fields" <bfields@fieldses.org>,
	Benjamin Coddington <bcodding@redhat.com>,
	Al Viro <viro@ZenIV.linux.org.uk>,
	Jeff Layton <jeff.layton@primarydata.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [RFC PATCH 5 2/7] kmod - teach usermodehelper to use service workqueues
Date: Tue, 31 Mar 2015 11:14:50 +0800	[thread overview]
Message-ID: <20150331031449.10464.73117.stgit@pluto.fritz.box> (raw)
In-Reply-To: <20150331030340.10464.30272.stgit@pluto.fritz.box>

The call_usermodehelper() function executes all binaries in the
global "init" root context. This doesn't allow a binary to be run
within a namespace environment such as a container. To do this
the namespace environment of the contaner must be available to
provide the required execution environment.

This can be done by creating a service thread, identified by
issuing a token identifier, used when executing the helper
with a function that takes the token as a parameter.

Signed-off-by: Ian Kent <ikent@redhat.com>
Cc: Benjamin Coddington <bcodding@redhat.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: J. Bruce Fields <bfields@fieldses.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Trond Myklebust <trond.myklebust@primarydata.com>
Cc: Oleg Nesterov <onestero@redhat.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Jeff Layton <jeff.layton@primarydata.com>
---
 include/linux/kmod.h |    5 +++++
 kernel/kmod.c        |   38 +++++++++++++++++++++++++++++++-------
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index fa46722..9a9fcb3 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -56,6 +56,7 @@ struct file;
 struct subprocess_info {
 	struct work_struct work;
 	struct completion *complete;
+	int wq_token;
 	char *path;
 	char **argv;
 	char **envp;
@@ -72,6 +73,10 @@ extern void umh_wq_put_token(int token);
 extern int
 call_usermodehelper(char *path, char **argv, char **envp, int wait);
 
+extern int
+call_usermodehelper_service(char *path, char **argv,
+			    char **envp, int token, int wait);
+
 extern struct subprocess_info *
 call_usermodehelper_setup(char *path, char **argv, char **envp, gfp_t gfp_mask,
 			  int (*init)(struct subprocess_info *info, struct cred *new),
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 55d20ce..47c5ff5 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -712,6 +712,7 @@ EXPORT_SYMBOL(call_usermodehelper_setup);
  */
 int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 {
+	static struct workqueue_struct *wq;
 	DECLARE_COMPLETION_ONSTACK(done);
 	int retval = 0;
 
@@ -720,7 +721,8 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 		return -EINVAL;
 	}
 	helper_lock();
-	if (!khelper_wq || usermodehelper_disabled) {
+	wq = umh_find_wq(sub_info->wq_token, wait);
+	if (!wq || usermodehelper_disabled) {
 		retval = -EBUSY;
 		goto out;
 	}
@@ -732,7 +734,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 	sub_info->complete = (wait == UMH_NO_WAIT) ? NULL : &done;
 	sub_info->wait = wait;
 
-	queue_work(khelper_wq, &sub_info->work);
+	queue_work(wq, &sub_info->work);
 	if (wait == UMH_NO_WAIT)	/* task has freed sub_info */
 		goto unlock;
 
@@ -759,19 +761,21 @@ unlock:
 EXPORT_SYMBOL(call_usermodehelper_exec);
 
 /**
- * call_usermodehelper() - prepare and start a usermode application
+ * call_usermodehelper_service() - start a usermode application within
+ * 				a service environment.
  * @path: path to usermode executable
  * @argv: arg vector for process
  * @envp: environment for process
+ * @token: token corresponding to a service environment obtained by a
+ * 	   call to umh_wq_get_token().
  * @wait: wait for the application to finish and return status.
  *        when UMH_NO_WAIT don't wait at all, but you get no useful error back
  *        when the program couldn't be exec'ed. This makes it safe to call
  *        from interrupt context.
- *
- * This function is the equivalent to use call_usermodehelper_setup() and
- * call_usermodehelper_exec().
  */
-int call_usermodehelper(char *path, char **argv, char **envp, int wait)
+int call_usermodehelper_service(char *path,
+				char **argv, char **envp,
+				int token, int wait)
 {
 	struct subprocess_info *info;
 	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
@@ -780,9 +784,29 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait)
 					 NULL, NULL, NULL);
 	if (info == NULL)
 		return -ENOMEM;
+	info->wq_token = token;
 
 	return call_usermodehelper_exec(info, wait);
 }
+EXPORT_SYMBOL(call_usermodehelper_service);
+
+/**
+ * call_usermodehelper() - prepare and start a usermode application
+ * @path: path to usermode executable
+ * @argv: arg vector for process
+ * @envp: environment for process
+ * @wait: wait for the application to finish and return status.
+ *        when UMH_NO_WAIT don't wait at all, but you get no useful error back
+ *        when the program couldn't be exec'ed. This makes it safe to call
+ *        from interrupt context.
+ *
+ * This function is the equivalent to using call_usermodehelper_setup() and
+ * call_usermodehelper_exec().
+ */
+int call_usermodehelper(char *path, char **argv, char **envp, int wait)
+{
+	return call_usermodehelper_service(path, argv, envp, 0, wait);
+}
 EXPORT_SYMBOL(call_usermodehelper);
 
 static int proc_cap_handler(struct ctl_table *table, int write,


  parent reply	other threads:[~2015-03-31  3:15 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-31  3:14 [RFC PATCH v5 0/7] Another attempt at contained helper execution Ian Kent
2015-03-31  3:14 ` [RFC PATCH 5 1/7] kmod - add workqueue service thread store Ian Kent
2015-03-31 11:21   ` Jeff Layton
2015-03-31 12:59     ` Ian Kent
2015-04-02 12:43   ` David Howells
2015-04-07  0:42     ` Ian Kent
2015-03-31  3:14 ` Ian Kent [this message]
2015-03-31  3:14 ` [RFC PATCH 5 3/7] nfsd - use service thread if not executing in init namespace Ian Kent
2015-03-31 13:14   ` J. Bruce Fields
2015-04-01  0:22     ` Ian Kent
2015-04-02 15:59       ` J. Bruce Fields
2015-03-31  3:15 ` [RFC PATCH 5 4/7] nfs - cache_lib " Ian Kent
2015-03-31  3:15 ` [RFC PATCH 5 5/7] nfs - objlayout " Ian Kent
2015-03-31  3:15 ` [RFC PATCH 5 6/7] KEYS - use correct memory allocation flag in call_usermodehelper_keys() Ian Kent
2015-04-02 13:00   ` David Howells
2015-03-31  3:15 ` [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator Ian Kent
2015-04-02 12:58   ` David Howells
2015-04-07  0:54     ` Ian Kent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150331031449.10464.73117.stgit@pluto.fritz.box \
    --to=raven@themaw.net \
    --cc=bcodding@redhat.com \
    --cc=bfields@fieldses.org \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=jeff.layton@primarydata.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=onestero@redhat.com \
    --cc=trond.myklebust@primarydata.com \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.