mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 09:00:12 +00:00
pidfs: protect PIDFD_GET_* ioctls() via ifdef
We originally protected PIDFD_GET_<ns-type>_NAMESPACE ioctls() through ifdefs and recent rework made it possible to drop them. There was an oversight though. When the relevant namespace is turned off ns->ops will be NULL so even though opening a file descriptor is perfectly legitimate it would fail during inode eviction when the file was closed. The simple fix would be to check ns->ops for NULL and continue allow to retrieve namespace fds from pidfds but we don't allow retrieving them when the relevant namespace type is turned off. So keep the simplification but add the ifdefs back in. Link: https://lore.kernel.org/20251222214907.GA189632@quark Link: https://patch.msgid.link/20251224-ununterbrochen-gagen-ea949b83f8f2@brauner Fixes: a71e4f103aed ("pidfs: simplify PIDFD_GET_<type>_NAMESPACE ioctls") Tested-by: Brendan Jackman <jackmanb@kernel.org> Tested-by: Eric Biggers <ebiggers@kernel.org> Reported-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
78c850021d
commit
75ddaa4ddc
18
fs/pidfs.c
18
fs/pidfs.c
@ -517,14 +517,18 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
switch (cmd) {
|
||||
/* Namespaces that hang of nsproxy. */
|
||||
case PIDFD_GET_CGROUP_NAMESPACE:
|
||||
#ifdef CONFIG_CGROUPS
|
||||
if (!ns_ref_get(nsp->cgroup_ns))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->cgroup_ns);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_IPC_NAMESPACE:
|
||||
#ifdef CONFIG_IPC_NS
|
||||
if (!ns_ref_get(nsp->ipc_ns))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->ipc_ns);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_MNT_NAMESPACE:
|
||||
if (!ns_ref_get(nsp->mnt_ns))
|
||||
@ -532,32 +536,43 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
ns_common = to_ns_common(nsp->mnt_ns);
|
||||
break;
|
||||
case PIDFD_GET_NET_NAMESPACE:
|
||||
#ifdef CONFIG_NET_NS
|
||||
if (!ns_ref_get(nsp->net_ns))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->net_ns);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE:
|
||||
#ifdef CONFIG_PID_NS
|
||||
if (!ns_ref_get(nsp->pid_ns_for_children))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->pid_ns_for_children);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_TIME_NAMESPACE:
|
||||
#ifdef CONFIG_TIME_NS
|
||||
if (!ns_ref_get(nsp->time_ns))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->time_ns);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE:
|
||||
#ifdef CONFIG_TIME_NS
|
||||
if (!ns_ref_get(nsp->time_ns_for_children))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->time_ns_for_children);
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_UTS_NAMESPACE:
|
||||
#ifdef CONFIG_UTS_NS
|
||||
if (!ns_ref_get(nsp->uts_ns))
|
||||
break;
|
||||
ns_common = to_ns_common(nsp->uts_ns);
|
||||
#endif
|
||||
break;
|
||||
/* Namespaces that don't hang of nsproxy. */
|
||||
case PIDFD_GET_USER_NAMESPACE:
|
||||
#ifdef CONFIG_USER_NS
|
||||
scoped_guard(rcu) {
|
||||
struct user_namespace *user_ns;
|
||||
|
||||
@ -566,8 +581,10 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
ns_common = to_ns_common(user_ns);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case PIDFD_GET_PID_NAMESPACE:
|
||||
#ifdef CONFIG_PID_NS
|
||||
scoped_guard(rcu) {
|
||||
struct pid_namespace *pid_ns;
|
||||
|
||||
@ -576,6 +593,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
ns_common = to_ns_common(pid_ns);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user