[RFC PATCH] fs: call_usermodehelper_root helper introduced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Usermode helper executes all binaries in global "init" root context. This
doesn't allow to call a binary from other root context (for example in a
container).
Currently, both containerized NFS client and NFS server requires an ability to
execute a binary in a container's root context. Root swap can be done in
"init" callback, passed by UMH caller.
But since we have 2 callers already (and more of them are expected to appear
in future) and because set_fs_root() in not exported, it looks reasonable to
add one more generic UMH helper to generic fs code.
Root path reference must be hold by the caller, since it will be put on UMH
thread exit.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@xxxxxxxxxxxxx>
---
 fs/fs_struct.c            |   28 ++++++++++++++++++++++++++++
 include/linux/fs_struct.h |    4 ++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index d8ac61d..cd1de8e 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
 #include <linux/path.h>
 #include <linux/slab.h>
 #include <linux/fs_struct.h>
+#include <linux/kmod.h>
 #include "internal.h"
 
 /*
@@ -157,6 +158,33 @@ int current_umask(void)
 }
 EXPORT_SYMBOL(current_umask);
 
+static int umh_set_fs_root(struct subprocess_info *info, struct cred *new)
+{
+	set_fs_root(current->fs, info->data);
+	return 0;
+}
+
+/*
+ * Call a usermode helper with a specific fs root.
+ *
+ * The caller must hold extra reference to it otherwise, because it will be
+ * put on usermodehelper thread exit.
+ */
+int call_usermodehelper_root(char *path, char **argv, char **envp,
+			     struct path *root, int wait)
+{
+	struct subprocess_info *info;
+	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
+
+	info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
+					      umh_set_fs_root, NULL, root);
+	if (info == NULL)
+		return -ENOMEM;
+
+	return call_usermodehelper_exec(info, wait);
+}
+EXPORT_SYMBOL(call_usermodehelper_root);
+
 /* to be mentioned only in INIT_TASK */
 struct fs_struct init_fs = {
 	.users		= 1,
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index 2b93a9a..cead51e 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -52,4 +52,8 @@ static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
 
 extern bool current_chrooted(void);
 
+extern int
+call_usermodehelper_root(char *path, char **argv, char **envp,
+			 struct path *root, int wait);
+
 #endif /* _LINUX_FS_STRUCT_H */

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux