aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kerrisk (man-pages) <mtk.manpages@gmail.com>2017-01-24 20:04:15 -0500
committerEric W. Biederman <ebiederm@xmission.com>2017-02-02 20:35:43 -0500
commitd95fa3c76a66b6d76b1e109ea505c55e66360f3c (patch)
tree17b13fb4290e9e4af97b1557b35d57fbb8099103
parente5ff5ce6e20ee22511398bb31fb912466cf82a36 (diff)
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>
-rw-r--r--fs/nsfs.c11
-rw-r--r--include/uapi/linux/nsfs.h8
2 files changed, 16 insertions, 3 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 @@
7#include <linux/seq_file.h> 7#include <linux/seq_file.h>
8#include <linux/user_namespace.h> 8#include <linux/user_namespace.h>
9#include <linux/nsfs.h> 9#include <linux/nsfs.h>
10#include <linux/uaccess.h>
10 11
11static struct vfsmount *nsfs_mnt; 12static struct vfsmount *nsfs_mnt;
12 13
@@ -163,7 +164,10 @@ int open_related_ns(struct ns_common *ns,
163static long ns_ioctl(struct file *filp, unsigned int ioctl, 164static long ns_ioctl(struct file *filp, unsigned int ioctl,
164 unsigned long arg) 165 unsigned long arg)
165{ 166{
167 struct user_namespace *user_ns;
166 struct ns_common *ns = get_proc_ns(file_inode(filp)); 168 struct ns_common *ns = get_proc_ns(file_inode(filp));
169 uid_t __user *argp;
170 uid_t uid;
167 171
168 switch (ioctl) { 172 switch (ioctl) {
169 case NS_GET_USERNS: 173 case NS_GET_USERNS:
@@ -174,6 +178,13 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
174 return open_related_ns(ns, ns->ops->get_parent); 178 return open_related_ns(ns, ns->ops->get_parent);
175 case NS_GET_NSTYPE: 179 case NS_GET_NSTYPE:
176 return ns->ops->type; 180 return ns->ops->type;
181 case NS_GET_OWNER_UID:
182 if (ns->ops->type != CLONE_NEWUSER)
183 return -EINVAL;
184 user_ns = container_of(ns, struct user_namespace, ns);
185 argp = (uid_t __user *) arg;
186 uid = from_kuid_munged(current_user_ns(), user_ns->owner);
187 return put_user(uid, argp);
177 default: 188 default:
178 return -ENOTTY; 189 return -ENOTTY;
179 } 190 }
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
index 2b48df11056a..1a3ca79f466b 100644
--- a/include/uapi/linux/nsfs.h
+++ b/include/uapi/linux/nsfs.h
@@ -6,11 +6,13 @@
6#define NSIO 0xb7 6#define NSIO 0xb7
7 7
8/* Returns a file descriptor that refers to an owning user namespace */ 8/* Returns a file descriptor that refers to an owning user namespace */
9#define NS_GET_USERNS _IO(NSIO, 0x1) 9#define NS_GET_USERNS _IO(NSIO, 0x1)
10/* Returns a file descriptor that refers to a parent namespace */ 10/* Returns a file descriptor that refers to a parent namespace */
11#define NS_GET_PARENT _IO(NSIO, 0x2) 11#define NS_GET_PARENT _IO(NSIO, 0x2)
12/* Returns the type of namespace (CLONE_NEW* value) referred to by 12/* Returns the type of namespace (CLONE_NEW* value) referred to by
13 file descriptor */ 13 file descriptor */
14#define NS_GET_NSTYPE _IO(NSIO, 0x3) 14#define NS_GET_NSTYPE _IO(NSIO, 0x3)
15/* Get owner UID (in the caller's user namespace) for a user namespace */
16#define NS_GET_OWNER_UID _IO(NSIO, 0x4)
15 17
16#endif /* __LINUX_NSFS_H */ 18#endif /* __LINUX_NSFS_H */