On Wed, Mar 27, 2019 at 06:07:54PM +0100, Jann Horn wrote: > On Wed, Mar 27, 2019 at 5:22 PM Christian Brauner <christian@xxxxxxxxxx> wrote: > > pidfd_open() allows to retrieve pidfds for processes and removes the > > dependency of pidfd on procfs. Multiple people have expressed a desire to > > do this even when pidfd_send_signal() was merged. It is even recorded in > [...] > > IF PROCFD_TO_PIDFD is passed as a flag together with a file descriptor to a > > /proc mount in a given pid namespace and a pidfd pidfd_open() will return a > > file descriptor to the corresponding /proc/<pid> directory in procfs > > mounts' pid namespace. pidfd_open() is very careful to verify that the pid > > nit: s/mounts'/mount's/ Thanks. > > > hasn't been recycled in between. > > IF PIDFD_TO_PROCFD is passed as a flag together with a file descriptor > > referencing a /proc/<pid> directory a pidfd referencing the struct pid > > stashed in /proc/<pid> of the process will be returned. > > nit: s/of the process //? Yes. > > > The pidfd_open() syscalls in that manner resembles openat() as it uses a > > nit: s/syscalls/syscall/ Thanks. > > [...] > > diff --git a/kernel/pid.c b/kernel/pid.c > > index 20881598bdfa..c9e24e726aba 100644 > > --- a/kernel/pid.c > > +++ b/kernel/pid.c > [...] > > +static struct file *pidfd_open_proc_pid(const struct file *procf, pid_t pid, > > + const struct pid *pidfd_pid) > > +{ > > + char name[11]; /* int to strlen + \0 */ > > nit: The comment is a bit off; an unconstrained int needs 1+10+1 > bytes, I think? minus sign, 10 digits, nullbyte? But of course that > can't actually happen here. Yes, the comment is misleading. > > > + struct file *file; > > + struct pid *proc_pid; > > + > > + snprintf(name, sizeof(name), "%d", pid); > > + file = file_open_root(procf->f_path.dentry, procf->f_path.mnt, name, > > + O_DIRECTORY | O_NOFOLLOW, 0); > > Maybe explicitly write the implied O_RDONLY (which is 0) here for clarity? Yes. > > [...] > > +static int pidfd_to_procfd(pid_t pid, int procfd, int pidfd) > > +{ > > + long fd; > > + pid_t ns_pid; > > + struct fd fdproc, fdpid; > > + struct file *file = NULL; > > + struct pid *pidfd_pid = NULL; > > + struct pid_namespace *proc_pid_ns = NULL; > > + > > + fdproc = fdget(procfd); > > + if (!fdproc.file) > > + return -EBADF; > > + > > + fdpid = fdget(pidfd); > > + if (!fdpid.file) { > > + fdput(fdpid); > > Typo: s/fdput(fdpid)/fdput(fdproc)/ Good catch! > > [...] > > +SYSCALL_DEFINE4(pidfd_open, pid_t, pid, int, procfd, int, pidfd, unsigned int, > > + flags) > [...] > > + if (!flags) { > [...] > > + rcu_read_lock(); > > + pidfd_pid = get_pid(find_pid_ns(pid, task_active_pid_ns(current))); > > + rcu_read_unlock(); > > The previous three lines are equivalent to `pidfd_pid = find_get_pid(pid)`. Perfect, will replace. > > > + fd = pidfd_create_fd(pidfd_pid, O_CLOEXEC); > > Nit: You could hardcode O_CLOEXEC in pidfd_create_fd() and get rid of > the second function argument if you want to. Hm, let me rename this to pidfd_create_cloexec(pidfd_pid) then. > > > + put_pid(pidfd_pid); > > + } else if (flags & PIDFD_TO_PROCFD) { > [...] > > + fd = pidfd_to_procfd(pid, procfd, pidfd); > > The `pid` argument of pidfd_to_procfd() looks unused, maybe it makes > sense to get rid of that? Yes.