Skip to content

Commit d95fa3c

Browse files
mkerriskebiederm
authored andcommitted
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 <[email protected]> Signed-off-by: Michael Kerrisk <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent e5ff5ce commit d95fa3c

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

fs/nsfs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/seq_file.h>
88
#include <linux/user_namespace.h>
99
#include <linux/nsfs.h>
10+
#include <linux/uaccess.h>
1011

1112
static struct vfsmount *nsfs_mnt;
1213

@@ -163,7 +164,10 @@ int open_related_ns(struct ns_common *ns,
163164
static long ns_ioctl(struct file *filp, unsigned int ioctl,
164165
unsigned long arg)
165166
{
167+
struct user_namespace *user_ns;
166168
struct ns_common *ns = get_proc_ns(file_inode(filp));
169+
uid_t __user *argp;
170+
uid_t uid;
167171

168172
switch (ioctl) {
169173
case NS_GET_USERNS:
@@ -174,6 +178,13 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
174178
return open_related_ns(ns, ns->ops->get_parent);
175179
case NS_GET_NSTYPE:
176180
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);
177188
default:
178189
return -ENOTTY;
179190
}

include/uapi/linux/nsfs.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
#define NSIO 0xb7
77

88
/* 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)
1010
/* 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)
1212
/* Returns the type of namespace (CLONE_NEW* value) referred to by
1313
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)
1517

1618
#endif /* __LINUX_NSFS_H */

0 commit comments

Comments
 (0)