@@ -1943,6 +1943,91 @@ const struct file_operations pidfd_fops = {
1943
1943
#endif
1944
1944
};
1945
1945
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
+
1946
2031
static void __delayed_free_task (struct rcu_head * rhp )
1947
2032
{
1948
2033
struct task_struct * tsk = container_of (rhp , struct task_struct , rcu );
0 commit comments