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 v4 07/12] kmod - add call_usermodehelper_ns()
Date: Tue, 17 Mar 2015 10:45:36 +0800	[thread overview]
Message-ID: <20150317024535.24592.77388.stgit@pluto.fritz.box> (raw)
In-Reply-To: <20150317022308.24592.35785.stgit@pluto.fritz.box>

From: Ian Kent <ikent@redhat.com>

Add function call_usermodehelper_ns() to allow passing a namespace
token to lookup previously stored namespace information for usermode
helper execution.

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 |   24 +++++++++++++
 kernel/kmod.c        |   96 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 77f41ce..a761650 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -87,9 +87,33 @@ static inline long umh_ns_get_token(long token)
 static inline void umh_ns_put_token(long token)
 {
 }
+
+static inline int
+call_usermodehelper_ns(char *path, char **argv, char **envp,
+		       unsigned int flags, long token)
+{
+	return -ENOTSUP;
+}
+
+static inline struct subprocess_info *
+call_usermodehelper_setup_ns(char *path, char **argv, char **envp, gfp_t gfp_mask,
+			     int (*init)(struct subprocess_info *info, struct cred *new),
+			     void (*cleanup)(struct subprocess_info *), void *data,
+			     long token)
+{
+	return -ENOTSUP;
+}
 #else
 extern long umh_ns_get_token(long token);
 extern void umh_ns_put_token(long token);
+extern int
+call_usermodehelper_ns(char *path, char **argv, char **envp,
+		       unsigned int flags, long token);
+extern struct subprocess_info *
+call_usermodehelper_setup_ns(char *path, char **argv, char **envp, gfp_t gfp_mask,
+			     int (*init)(struct subprocess_info *info, struct cred *new),
+			     void (*cleanup)(struct subprocess_info *), void *data,
+			     long token);
 #endif
 
 extern int
diff --git a/kernel/kmod.c b/kernel/kmod.c
index ddd41f1..d711240 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -842,6 +842,62 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
 }
 EXPORT_SYMBOL(call_usermodehelper_setup);
 
+#ifdef CONFIG_NAMESPACES
+/**
+ * call_usermodehelper_setup_ns - prepare to call a usermode helper
+ * 			within a namespace
+ * @path: path to usermode executable
+ * @argv: arg vector for process
+ * @envp: environment for process
+ * @gfp_mask: gfp mask for memory allocation
+ * @cleanup: a cleanup function
+ * @init: an init function
+ * @data: arbitrary context sensitive data
+ * @token: token used to locate namespace setup.
+ *
+ * Returns either an errno error cast, or a subprocess_info structure.
+ * This should be passed to call_usermodehelper_exec to exec the process
+ * and free the structure.
+ *
+ * The init function is used to customize the helper process prior to
+ * exec.  A non-zero return code causes the process to error out, exit,
+ * and return the failure to the calling process
+ *
+ * The cleanup function is run just before the subprocess_info is about
+ * to be freed.  This can be used for freeing the argv and envp.  The
+ * Function must be runnable in either a process context or the
+ * context in which call_usermodehelper_exec is called.
+ */
+struct subprocess_info *call_usermodehelper_setup_ns(char *path, char **argv,
+		char **envp, gfp_t gfp_mask,
+		int (*init)(struct subprocess_info *info, struct cred *new),
+		void (*cleanup)(struct subprocess_info *info),
+		void *data, long token)
+{
+	struct subprocess_info *info;
+	unsigned int nowait = gfp_mask == GFP_ATOMIC ? 1 : 0;
+	struct umh_ns_entry *entry;
+
+	info = call_usermodehelper_setup(path, argv, envp,
+					 gfp_mask, NULL, NULL, NULL);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+	entry = umh_ns_find_entry(token, nowait);
+	if (IS_ERR(entry)) {
+		kfree(info);
+		info = ERR_CAST(entry);
+		goto out;
+	}
+	get_nsproxy(entry->nsinfo.nsproxy);
+	info->nsinfo.nsproxy = entry->nsinfo.nsproxy;
+	info->nsinfo.user_ns = get_user_ns(entry->nsinfo.user_ns);
+out:
+	return info;
+}
+EXPORT_SYMBOL(call_usermodehelper_setup_ns);
+#endif /* CONFIG_NAMESPACES */
+
 /**
  * call_usermodehelper_exec - start a usermode application
  * @sub_info: information about the subprocessa
@@ -939,6 +995,46 @@ int call_usermodehelper(char *path,
 }
 EXPORT_SYMBOL(call_usermodehelper);
 
+#ifdef CONFIG_NAMESPACES
+/**
+ * call_usermodehelper_ns() - prepare and start a usermode application and
+ * 			execute using the stored namspace information
+ * 			corresponding to the passed token
+ * @path: path to usermode executable
+ * @argv: arg vector for process
+ * @envp: environment for process
+ * @flags: 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.
+ * @token: key of stored namespace to use or 0 to use the namespace of
+ * 	  init process of the caller.
+ *
+ * Returns 0 or an errno error if not successful.
+ */
+int call_usermodehelper_ns(char *path, char **argv, char **envp,
+			   unsigned int flags, long token)
+{
+	struct subprocess_info *info;
+	unsigned int nowait = flags & UMH_NO_WAIT;
+	gfp_t gfp_mask = nowait ? GFP_ATOMIC : GFP_KERNEL;
+
+	if (token < 0)
+		return -EINVAL;
+
+	if (!token)
+		return call_usermodehelper(path, argv, envp, flags|UMH_USE_NS);
+
+	info = call_usermodehelper_setup_ns(path, argv, envp,
+					    gfp_mask, NULL, NULL, NULL, token);
+	if (IS_ERR(info))
+		return PTR_ERR(info);
+
+	return call_usermodehelper_exec(info, flags|UMH_USE_NS);
+}
+EXPORT_SYMBOL(call_usermodehelper_ns);
+#endif /* CONFIG_NAMESPACES */
+
 static int proc_cap_handler(struct ctl_table *table, int write,
 			 void __user *buffer, size_t *lenp, loff_t *ppos)
 {


  parent reply	other threads:[~2015-03-17  2:45 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-17  2:44 [RFC PATCH v4 00/12] Second attempt at contained helper execution Ian Kent
2015-03-17  2:44 ` [RFC PATCH v4 01/12] nsproxy - make create_new_namespaces() non-static Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 02/12] kmod - rename call_usermodehelper() flags parameter Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 03/12] vfs - move mnt_namespace definition to linux/mount.h Ian Kent
2015-03-19 19:47   ` Al Viro
2015-03-20  0:57     ` Ian Kent
2015-03-20  1:14       ` Eric W. Biederman
2015-03-20  2:11         ` Ian Kent
2015-03-20  2:47         ` Al Viro
2015-03-17  2:45 ` [RFC PATCH v4 04/12] kmod - add namespace aware thread runner Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 05/12] kmod - teach call_usermodehelper() to use a namespace Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 06/12] kmod - add namespace info store Ian Kent
2015-03-17  2:45 ` Ian Kent [this message]
2015-03-17  2:45 ` [RFC PATCH v4 08/12] nfsd - use namespace if not executing in init namespace Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 09/12] nfs - cache_lib " Ian Kent
2015-03-17  2:45 ` [RFC PATCH v4 10/12] nfs - objlayout " Ian Kent
2015-03-17  2:46 ` [RFC PATCH v4 11/12] KEYS - use correct memory allocation flag in call_usermodehelper_keys() Ian Kent
2015-03-17  2:46 ` [RFC PATCH v4 12/12] KEYS: exec request-key within the requesting task's init namespace Ian Kent
2015-03-18 17:41 ` [RFC PATCH v4 00/12] Second attempt at contained helper execution J. Bruce Fields
2015-03-19 21:38 ` Eric W. Biederman
2015-03-20  2:10   ` 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=20150317024535.24592.77388.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.