Unverified Commit e6b899f0 authored by Christian Brauner's avatar Christian Brauner
Browse files

nsfs: tighten permission checks for ns iteration ioctls

Even privileged services should not necessarily be able to see other
privileged service's namespaces so they can't leak information to each
other. Use may_see_all_namespaces() helper that centralizes this policy
until the nstree adapts.

Link: https://patch.msgid.link/20260226-work-visibility-fixes-v1-1-d2c2853313bd@kernel.org


Fixes: a1d220d9 ("nsfs: iterate through mount namespaces")
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Cc: stable@kernel.org # v6.12+
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent a0b4c7a4
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -199,6 +199,17 @@ static bool nsfs_ioctl_valid(unsigned int cmd)
	return false;
}

static bool may_use_nsfs_ioctl(unsigned int cmd)
{
	switch (_IOC_NR(cmd)) {
	case _IOC_NR(NS_MNT_GET_NEXT):
		fallthrough;
	case _IOC_NR(NS_MNT_GET_PREV):
		return may_see_all_namespaces();
	}
	return true;
}

static long ns_ioctl(struct file *filp, unsigned int ioctl,
			unsigned long arg)
{
@@ -214,6 +225,8 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,

	if (!nsfs_ioctl_valid(ioctl))
		return -ENOIOCTLCMD;
	if (!may_use_nsfs_ioctl(ioctl))
		return -EPERM;

	ns = get_proc_ns(file_inode(filp));
	switch (ioctl) {
+2 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ static __always_inline bool is_ns_init_id(const struct ns_common *ns)

#define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns)))

bool may_see_all_namespaces(void);

static __always_inline __must_check int __ns_ref_active_read(const struct ns_common *ns)
{
	return atomic_read(&ns->__ns_ref_active);
+6 −0
Original line number Diff line number Diff line
@@ -309,3 +309,9 @@ void __ns_ref_active_get(struct ns_common *ns)
			return;
	}
}

bool may_see_all_namespaces(void)
{
	return (task_active_pid_ns(current) == &init_pid_ns) &&
	       ns_capable_noaudit(init_pid_ns.user_ns, CAP_SYS_ADMIN);
}