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 04/12] kmod - add namespace aware thread runner
Date: Tue, 17 Mar 2015 10:45:16 +0800 [thread overview]
Message-ID: <20150317024515.24592.64333.stgit@pluto.fritz.box> (raw)
In-Reply-To: <20150317022308.24592.35785.stgit@pluto.fritz.box>
From: Ian Kent <ikent@redhat.com>
Make usermode helper thread runner namespace aware.
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 | 12 ++++++
kernel/kmod.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index e647ddb..64c81c9 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -25,6 +25,7 @@
#include <linux/compiler.h>
#include <linux/workqueue.h>
#include <linux/sysctl.h>
+#include <linux/user_namespace.h>
#define KMOD_PATH_LEN 256
@@ -52,6 +53,14 @@ struct file;
#define UMH_WAIT_EXEC 1 /* wait for the exec, but not the process */
#define UMH_WAIT_PROC 2 /* wait for the process to complete */
#define UMH_KILLABLE 4 /* wait for EXEC/PROC killable */
+#define UMH_USE_NS 32 /* exec using caller's init namespace */
+
+#ifdef CONFIG_NAMESPACES
+struct umh_ns_info {
+ struct nsproxy *nsproxy;
+ struct user_namespace *user_ns;
+};
+#endif
struct subprocess_info {
struct work_struct work;
@@ -64,6 +73,9 @@ struct subprocess_info {
int (*init)(struct subprocess_info *info, struct cred *new);
void (*cleanup)(struct subprocess_info *info);
void *data;
+#ifdef CONFIG_NAMESPACES
+ struct umh_ns_info nsinfo;
+#endif
};
extern int
diff --git a/kernel/kmod.c b/kernel/kmod.c
index e968e2d..213dbe0 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -39,6 +39,7 @@
#include <linux/rwsem.h>
#include <linux/ptrace.h>
#include <linux/async.h>
+#include <linux/proc_ns.h>
#include <asm/uaccess.h>
#include <trace/events/module.h>
@@ -303,11 +304,8 @@ static int wait_for_helper(void *data)
do_exit(0);
}
-/* This is run by khelper thread */
-static void __call_usermodehelper(struct work_struct *work)
+static pid_t umh_kernel_thread(struct subprocess_info *sub_info)
{
- struct subprocess_info *sub_info =
- container_of(work, struct subprocess_info, work);
pid_t pid;
if (sub_info->flags & UMH_WAIT_PROC)
@@ -316,7 +314,99 @@ static void __call_usermodehelper(struct work_struct *work)
else
pid = kernel_thread(____call_usermodehelper, sub_info,
SIGCHLD);
+ return pid;
+}
+
+#ifndef CONFIG_NAMESPACES
+static pid_t umh_kernel_thread_in_ns(struct subprocess_info *sub_info)
+{
+ return -ENOTSUP;
+}
+#else
+static pid_t umh_kernel_thread_in_ns(struct subprocess_info *sub_info)
+{
+ struct umh_ns_info *info = &sub_info->nsinfo;
+ struct nsproxy *saved_nsp, *new_nsp;
+ struct user_namespace *user_ns;
+ struct pid_namespace *pid_ns;
+ struct mnt_namespace *mnt_ns;
+ pid_t pid;
+ int err;
+
+ saved_nsp = current->nsproxy;
+ get_nsproxy(saved_nsp);
+
+ new_nsp = info->nsproxy;
+ get_nsproxy(new_nsp);
+
+ user_ns = get_user_ns(current->cred->user_ns);
+ if (info->user_ns) {
+ err = user_ns->ns.ops->install(new_nsp, &info->user_ns->ns);
+ if (err)
+ goto out;
+ }
+
+ /* May need to wait4() completion so a pid valid in the
+ * thread runners namespace is needed. Install current
+ * pid ns in the nsproxy.
+ */
+ pid_ns = current->nsproxy->pid_ns_for_children;
+ if (pid_ns) {
+ err = pid_ns->ns.ops->install(new_nsp, &pid_ns->ns);
+ if (err)
+ goto out_user_ns;
+ }
+
+ /* The mount namespace install function is a little
+ * more than a no-op, as the install functions of the
+ * other namespace types are in our case, we need to
+ * call it to setup current fs root and pwd.
+ */
+ mnt_ns = current->nsproxy->mnt_ns;
+ err = mnt_ns->ns.ops->install(new_nsp, &new_nsp->mnt_ns->ns);
+ if (err)
+ goto out_user_ns;
+ /* Finally, switch to the nsproxy of the init namespace
+ * of the caller.
+ */
+ switch_task_namespaces(current, new_nsp);
+
+ pid = umh_kernel_thread(sub_info);
+
+ mnt_ns->ns.ops->install(saved_nsp, &saved_nsp->mnt_ns->ns);
+
+ if (info->user_ns)
+ user_ns->ns.ops->install(saved_nsp, &user_ns->ns);
+
+ switch_task_namespaces(current, saved_nsp);
+
+ put_user_ns(user_ns);
+
+ return pid;
+
+out_user_ns:
+ if (info->user_ns)
+ user_ns->ns.ops->install(saved_nsp, &user_ns->ns);
+out:
+ put_user_ns(user_ns);
+ put_nsproxy(new_nsp);
+ put_nsproxy(saved_nsp);
+ return err;
+}
+#endif
+
+/* This is run by khelper thread */
+static void __call_usermodehelper(struct work_struct *work)
+{
+ struct subprocess_info *sub_info =
+ container_of(work, struct subprocess_info, work);
+ pid_t pid;
+
+ if (sub_info->flags & UMH_USE_NS)
+ pid = umh_kernel_thread_in_ns(sub_info);
+ else
+ pid = umh_kernel_thread(sub_info);
if (pid < 0) {
sub_info->retval = pid;
umh_complete(sub_info);
next prev 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 ` Ian Kent [this message]
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 ` [RFC PATCH v4 07/12] kmod - add call_usermodehelper_ns() Ian Kent
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=20150317024515.24592.64333.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.