On 2025-09-10, Christian Brauner <[email protected]> wrote: > The mount namespace has supported id retrieval for a while already. > Add support for the other types as well. > > Signed-off-by: Christian Brauner <[email protected]> > --- > 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...
> +
> + 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/
signature.asc
Description: PGP signature
