summaryrefslogtreecommitdiff
path: root/fs/nsfs.c
diff options
context:
space:
mode:
authorMichael Kerrisk (man-pages) <mtk.manpages@gmail.com>2017-01-25 14:04:15 +1300
committerEric W. Biederman <ebiederm@xmission.com>2017-02-03 14:35:43 +1300
commitd95fa3c76a66b6d76b1e109ea505c55e66360f3c (patch)
tree17b13fb4290e9e4af97b1557b35d57fbb8099103 /fs/nsfs.c
parente5ff5ce6e20ee22511398bb31fb912466cf82a36 (diff)
downloadlwn-d95fa3c76a66b6d76b1e109ea505c55e66360f3c.tar.gz
lwn-d95fa3c76a66b6d76b1e109ea505c55e66360f3c.zip
nsfs: Add an ioctl() to return owner UID of a userns
I'd like to write code that discovers the user namespace hierarchy on a running system, and also shows who owns the various user namespaces. Currently, there is no way of getting the owner UID of a user namespace. Therefore, this patch adds a new NS_GET_CREATOR_UID ioctl() that fetches the UID (as seen in the user namespace of the caller) of the creator of the user namespace referred to by the specified file descriptor. If the supplied file descriptor does not refer to a user namespace, the operation fails with the error EINVAL. If the owner UID does not have a mapping in the caller's user namespace return the overflow UID as that appears easier to deal with in practice in user-space applications. -- EWB Changed the handling of unmapped UIDs from -EOVERFLOW back to the overflow uid. Per conversation with Michael Kerrisk after examining his test code. Acked-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Michael Kerrisk <mtk-manpages@gmail.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'fs/nsfs.c')
-rw-r--r--fs/nsfs.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 5d534763c662..1656843e87d2 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -7,6 +7,7 @@
#include <linux/seq_file.h>
#include <linux/user_namespace.h>
#include <linux/nsfs.h>
+#include <linux/uaccess.h>
static struct vfsmount *nsfs_mnt;
@@ -163,7 +164,10 @@ int open_related_ns(struct ns_common *ns,
static long ns_ioctl(struct file *filp, unsigned int ioctl,
unsigned long arg)
{
+ struct user_namespace *user_ns;
struct ns_common *ns = get_proc_ns(file_inode(filp));
+ uid_t __user *argp;
+ uid_t uid;
switch (ioctl) {
case NS_GET_USERNS:
@@ -174,6 +178,13 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
return open_related_ns(ns, ns->ops->get_parent);
case NS_GET_NSTYPE:
return ns->ops->type;
+ case NS_GET_OWNER_UID:
+ if (ns->ops->type != CLONE_NEWUSER)
+ return -EINVAL;
+ user_ns = container_of(ns, struct user_namespace, ns);
+ argp = (uid_t __user *) arg;
+ uid = from_kuid_munged(current_user_ns(), user_ns->owner);
+ return put_user(uid, argp);
default:
return -ENOTTY;
}