By adding the pidfd_create() declaration to linux/pid.h, it effectively exposes this function to the rest of the kernel. As the function currently stands, any part of the kernel could call pidfd_create() and the pidfd creation would not be subject to the same parameter constraints/checks as calling pidfd_open() would force upon a caller. This could lead to unintended behavior and/or misuse of the pidfd API. To mitigate this, the pid_has_task() check is rolled up into pidfd_create() and flags that are passed as parameter are checked for validity. Signed-off-by: Matthew Bobrowski <repnop@xxxxxxxxxx> --- kernel/pid.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/pid.c b/kernel/pid.c index d3cd95b8b080..1805cb3d74b7 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -559,6 +559,12 @@ int pidfd_create(struct pid *pid, unsigned int flags) { int fd; + if (!pid || !pid_has_task(pid, PIDTYPE_TGID)) + return -EINVAL; + + if (flags & ~(O_NONBLOCK | O_CLOEXEC | O_RDWR)) + return -EINVAL; + fd = anon_inode_getfd("[pidfd]", &pidfd_fops, get_pid(pid), flags | O_RDWR | O_CLOEXEC); if (fd < 0) @@ -598,10 +604,7 @@ SYSCALL_DEFINE2(pidfd_open, pid_t, pid, unsigned int, flags) if (!p) return -ESRCH; - if (pid_has_task(p, PIDTYPE_TGID)) - fd = pidfd_create(p, flags); - else - fd = -EINVAL; + fd = pidfd_create(p, flags); put_pid(p); return fd; -- 2.31.1.751.gd2f1c929bd-goog /M