Skip to content

Commit 1ced79b

Browse files
braunergregkh
authored andcommitted
pid: add pidfd_prepare()
commit 6ae930d9dbf2d093157be33428538c91966d8a9f upstream. Add a new helper that allows to reserve a pidfd and allocates a new pidfd file that stashes the provided struct pid. This will allow us to remove places that either open code this function or that call pidfd_create() but then have to call close_fd() because there are still failure points after pidfd_create() has been called. Reviewed-by: Jan Kara <[email protected]> Message-Id: <[email protected]> Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent fc7846a commit 1ced79b

File tree

3 files changed

+93
-12
lines changed

3 files changed

+93
-12
lines changed

include/linux/pid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern struct pid *pidfd_pid(const struct file *file);
8080
struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags);
8181
struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags);
8282
int pidfd_create(struct pid *pid, unsigned int flags);
83+
int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret);
8384

8485
static inline struct pid *get_pid(struct pid *pid)
8586
{

kernel/fork.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,91 @@ const struct file_operations pidfd_fops = {
19431943
#endif
19441944
};
19451945

1946+
/**
1947+
* __pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
1948+
* @pid: the struct pid for which to create a pidfd
1949+
* @flags: flags of the new @pidfd
1950+
* @pidfd: the pidfd to return
1951+
*
1952+
* Allocate a new file that stashes @pid and reserve a new pidfd number in the
1953+
* caller's file descriptor table. The pidfd is reserved but not installed yet.
1954+
1955+
* The helper doesn't perform checks on @pid which makes it useful for pidfds
1956+
* created via CLONE_PIDFD where @pid has no task attached when the pidfd and
1957+
* pidfd file are prepared.
1958+
*
1959+
* If this function returns successfully the caller is responsible to either
1960+
* call fd_install() passing the returned pidfd and pidfd file as arguments in
1961+
* order to install the pidfd into its file descriptor table or they must use
1962+
* put_unused_fd() and fput() on the returned pidfd and pidfd file
1963+
* respectively.
1964+
*
1965+
* This function is useful when a pidfd must already be reserved but there
1966+
* might still be points of failure afterwards and the caller wants to ensure
1967+
* that no pidfd is leaked into its file descriptor table.
1968+
*
1969+
* Return: On success, a reserved pidfd is returned from the function and a new
1970+
* pidfd file is returned in the last argument to the function. On
1971+
* error, a negative error code is returned from the function and the
1972+
* last argument remains unchanged.
1973+
*/
1974+
static int __pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret)
1975+
{
1976+
int pidfd;
1977+
struct file *pidfd_file;
1978+
1979+
if (flags & ~(O_NONBLOCK | O_RDWR | O_CLOEXEC))
1980+
return -EINVAL;
1981+
1982+
pidfd = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
1983+
if (pidfd < 0)
1984+
return pidfd;
1985+
1986+
pidfd_file = anon_inode_getfile("[pidfd]", &pidfd_fops, pid,
1987+
flags | O_RDWR | O_CLOEXEC);
1988+
if (IS_ERR(pidfd_file)) {
1989+
put_unused_fd(pidfd);
1990+
return PTR_ERR(pidfd_file);
1991+
}
1992+
get_pid(pid); /* held by pidfd_file now */
1993+
*ret = pidfd_file;
1994+
return pidfd;
1995+
}
1996+
1997+
/**
1998+
* pidfd_prepare - allocate a new pidfd_file and reserve a pidfd
1999+
* @pid: the struct pid for which to create a pidfd
2000+
* @flags: flags of the new @pidfd
2001+
* @pidfd: the pidfd to return
2002+
*
2003+
* Allocate a new file that stashes @pid and reserve a new pidfd number in the
2004+
* caller's file descriptor table. The pidfd is reserved but not installed yet.
2005+
*
2006+
* The helper verifies that @pid is used as a thread group leader.
2007+
*
2008+
* If this function returns successfully the caller is responsible to either
2009+
* call fd_install() passing the returned pidfd and pidfd file as arguments in
2010+
* order to install the pidfd into its file descriptor table or they must use
2011+
* put_unused_fd() and fput() on the returned pidfd and pidfd file
2012+
* respectively.
2013+
*
2014+
* This function is useful when a pidfd must already be reserved but there
2015+
* might still be points of failure afterwards and the caller wants to ensure
2016+
* that no pidfd is leaked into its file descriptor table.
2017+
*
2018+
* Return: On success, a reserved pidfd is returned from the function and a new
2019+
* pidfd file is returned in the last argument to the function. On
2020+
* error, a negative error code is returned from the function and the
2021+
* last argument remains unchanged.
2022+
*/
2023+
int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret)
2024+
{
2025+
if (!pid || !pid_has_task(pid, PIDTYPE_TGID))
2026+
return -EINVAL;
2027+
2028+
return __pidfd_prepare(pid, flags, ret);
2029+
}
2030+
19462031
static void __delayed_free_task(struct rcu_head *rhp)
19472032
{
19482033
struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);

kernel/pid.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -594,20 +594,15 @@ struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags)
594594
*/
595595
int pidfd_create(struct pid *pid, unsigned int flags)
596596
{
597-
int fd;
598-
599-
if (!pid || !pid_has_task(pid, PIDTYPE_TGID))
600-
return -EINVAL;
597+
int pidfd;
598+
struct file *pidfd_file;
601599

602-
if (flags & ~(O_NONBLOCK | O_RDWR | O_CLOEXEC))
603-
return -EINVAL;
604-
605-
fd = anon_inode_getfd("[pidfd]", &pidfd_fops, get_pid(pid),
606-
flags | O_RDWR | O_CLOEXEC);
607-
if (fd < 0)
608-
put_pid(pid);
600+
pidfd = pidfd_prepare(pid, flags, &pidfd_file);
601+
if (pidfd < 0)
602+
return pidfd;
609603

610-
return fd;
604+
fd_install(pidfd, pidfd_file);
605+
return pidfd;
611606
}
612607

613608
/**

0 commit comments

Comments
 (0)