Thread (78 messages) 78 messages, 12 authors, 2025-10-24

Re: [PATCH 29/32] nsfs: add missing id retrieval support

From: Aleksa Sarai <hidden>
Date: 2025-09-10 16:50:13
Also in: cgroups, linux-block, linux-fsdevel, linux-kselftest, linux-nfs, lkml

On 2025-09-10, Christian Brauner [off-list ref] wrote:
quoted hunk ↗ jump to hunk
The mount namespace has supported id retrieval for a while already.
Add support for the other types as well.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/nsfs.c                 | 74 +++++++++++++++++++++++++++++++++++++++--------
 include/uapi/linux/nsfs.h | 12 ++++++--
 2 files changed, 72 insertions(+), 14 deletions(-)
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 3c6fcf652633..527480e67fd1 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -173,6 +173,13 @@ static bool nsfs_ioctl_valid(unsigned int cmd)
 	case NS_GET_NSTYPE:
 	case NS_GET_OWNER_UID:
 	case NS_GET_MNTNS_ID:
+	case NS_GET_NETNS_ID:
+	case NS_GET_CGROUPNS_ID:
+	case NS_GET_IPCNS_ID:
+	case NS_GET_UTSNS_ID:
+	case NS_GET_PIDNS_ID:
+	case NS_GET_TIMENS_ID:
+	case NS_GET_USERNS_ID:
 	case NS_GET_PID_FROM_PIDNS:
 	case NS_GET_TGID_FROM_PIDNS:
 	case NS_GET_PID_IN_PIDNS:
@@ -226,18 +233,6 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
 		argp = (uid_t __user *) arg;
 		uid = from_kuid_munged(current_user_ns(), user_ns->owner);
 		return put_user(uid, argp);
-	case NS_GET_MNTNS_ID: {
-		__u64 __user *idp;
-		__u64 id;
-
-		if (ns->ops->type != CLONE_NEWNS)
-			return -EINVAL;
-
-		mnt_ns = container_of(ns, struct mnt_namespace, ns);
-		idp = (__u64 __user *)arg;
-		id = mnt_ns->ns.ns_id;
-		return put_user(id, idp);
-	}
 	case NS_GET_PID_FROM_PIDNS:
 		fallthrough;
 	case NS_GET_TGID_FROM_PIDNS:
@@ -283,6 +278,61 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
 			ret = -ESRCH;
 		return ret;
 	}
+	case NS_GET_MNTNS_ID:
+		fallthrough;
+	case NS_GET_NETNS_ID:
+		fallthrough;
+	case NS_GET_CGROUPNS_ID:
+		fallthrough;
+	case NS_GET_IPCNS_ID:
+		fallthrough;
+	case NS_GET_UTSNS_ID:
+		fallthrough;
+	case NS_GET_PIDNS_ID:
+		fallthrough;
+	case NS_GET_TIMENS_ID:
+		fallthrough;
+	case NS_GET_USERNS_ID: {
+		__u64 __user *idp;
+		__u64 id;
+		int expected_type;
+
+		switch (ioctl) {
+		case NS_GET_MNTNS_ID:
+			expected_type = CLONE_NEWNS;
+			break;
+		case NS_GET_NETNS_ID:
+			expected_type = CLONE_NEWNET;
+			break;
+		case NS_GET_CGROUPNS_ID:
+			expected_type = CLONE_NEWCGROUP;
+			break;
+		case NS_GET_IPCNS_ID:
+			expected_type = CLONE_NEWIPC;
+			break;
+		case NS_GET_UTSNS_ID:
+			expected_type = CLONE_NEWUTS;
+			break;
+		case NS_GET_PIDNS_ID:
+			expected_type = CLONE_NEWPID;
+			break;
+		case NS_GET_TIMENS_ID:
+			expected_type = CLONE_NEWTIME;
+			break;
+		case NS_GET_USERNS_ID:
+			expected_type = CLONE_NEWUSER;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if (ns->ops->type != expected_type)
+			return -EINVAL;
While I get that having this be per-ns-type lets programs avoid being
tricked into thinking that one namespace ID is actually another
namespace, it feels a bit ugly to have to add a new ioctl for every new
namespace.

If we added a way to get the CLONE_* flag for a namespace (NS_GET_TYPE)
we could have just NS_GET_ID. Of course, we would have to trust
userspace to do the right thing...
quoted hunk ↗ jump to hunk
+
+		idp = (__u64 __user *)arg;
+		id = ns->ns_id;
+		return put_user(id, idp);
+	}
 	}
 
 	/* extensible ioctls */
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
index 97d8d80d139f..f7c21840cc09 100644
--- a/include/uapi/linux/nsfs.h
+++ b/include/uapi/linux/nsfs.h
@@ -16,8 +16,6 @@
 #define NS_GET_NSTYPE		_IO(NSIO, 0x3)
 /* Get owner UID (in the caller's user namespace) for a user namespace */
 #define NS_GET_OWNER_UID	_IO(NSIO, 0x4)
-/* Get the id for a mount namespace */
-#define NS_GET_MNTNS_ID		_IOR(NSIO, 0x5, __u64)
 /* Translate pid from target pid namespace into the caller's pid namespace. */
 #define NS_GET_PID_FROM_PIDNS	_IOR(NSIO, 0x6, int)
 /* Return thread-group leader id of pid in the callers pid namespace. */
@@ -42,6 +40,16 @@ struct mnt_ns_info {
 /* Get previous namespace. */
 #define NS_MNT_GET_PREV		_IOR(NSIO, 12, struct mnt_ns_info)
 
+/* Retrieve namespace identifiers. */
+#define NS_GET_MNTNS_ID		_IOR(NSIO, 5,  __u64)
+#define NS_GET_NETNS_ID		_IOR(NSIO, 13, __u64)
+#define NS_GET_CGROUPNS_ID	_IOR(NSIO, 14, __u64)
+#define NS_GET_IPCNS_ID		_IOR(NSIO, 15, __u64)
+#define NS_GET_UTSNS_ID		_IOR(NSIO, 16, __u64)
+#define NS_GET_PIDNS_ID		_IOR(NSIO, 17, __u64)
+#define NS_GET_TIMENS_ID	_IOR(NSIO, 18, __u64)
+#define NS_GET_USERNS_ID	_IOR(NSIO, 19, __u64)
+
 enum init_ns_ino {
 	IPC_NS_INIT_INO		= 0xEFFFFFFFU,
 	UTS_NS_INIT_INO		= 0xEFFFFFFEU,
-- 
2.47.3
-- 
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH
https://www.cyphar.com/

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help