Skip to content

Commit 2775832

Browse files
mihalicynbrauner
authored andcommitted
af_unix: stash pidfs dentry when needed
We need to ensure that pidfs dentry is allocated when we meet any struct pid for the first time. This will allows us to open pidfd even after the task it corresponds to is reaped. Basically, we need to identify all places where we fill skb/scm_cookie with struct pid reference for the first time and call pidfs_register_pid(). Tricky thing here is that we have a few places where this happends depending on what userspace is doing: - [__scm_replace_pid()] explicitly sending an SCM_CREDENTIALS message and specified pid in a numeric format - [unix_maybe_add_creds()] enabled SO_PASSCRED/SO_PASSPIDFD but didn't send SCM_CREDENTIALS explicitly - [scm_send()] force_creds is true. Netlink case, we don't need to touch it. Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: David S. Miller <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Simon Horman <horms@kernel.org> Cc: Leon Romanovsky <leon@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Christian Brauner <brauner@kernel.org> Cc: Kuniyuki Iwashima <kuniyu@google.com> Cc: Lennart Poettering <mzxreary@0pointer.de> Cc: Luca Boccassi <bluca@debian.org> Cc: David Rheinsberg <david@readahead.eu> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Link: https://lore.kernel.org/20250703222314.309967-6-aleksandr.mikhalitsyn@canonical.com Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 2b99964 commit 2775832

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

net/core/scm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/security.h>
2424
#include <linux/pid_namespace.h>
2525
#include <linux/pid.h>
26+
#include <linux/pidfs.h>
2627
#include <linux/nsproxy.h>
2728
#include <linux/slab.h>
2829
#include <linux/errqueue.h>
@@ -147,9 +148,15 @@ EXPORT_SYMBOL(__scm_destroy);
147148

148149
static inline int scm_replace_pid(struct scm_cookie *scm, struct pid *pid)
149150
{
151+
int err;
152+
150153
/* drop all previous references */
151154
scm_destroy_cred(scm);
152155

156+
err = pidfs_register_pid(pid);
157+
if (unlikely(err))
158+
return err;
159+
153160
scm->pid = pid;
154161
scm->creds.pid = pid_vnr(pid);
155162
return 0;

net/unix/af_unix.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,7 @@ static void unix_skb_to_scm(struct sk_buff *skb, struct scm_cookie *scm)
19711971
* We include credentials if source or destination socket
19721972
* asserted SOCK_PASSCRED.
19731973
*
1974+
* Context: May sleep.
19741975
* Return: On success zero, on error a negative error code is returned.
19751976
*/
19761977
static int unix_maybe_add_creds(struct sk_buff *skb, const struct sock *sk,
@@ -1980,7 +1981,15 @@ static int unix_maybe_add_creds(struct sk_buff *skb, const struct sock *sk,
19801981
return 0;
19811982

19821983
if (unix_may_passcred(sk) || unix_may_passcred(other)) {
1983-
UNIXCB(skb).pid = get_pid(task_tgid(current));
1984+
struct pid *pid;
1985+
int err;
1986+
1987+
pid = task_tgid(current);
1988+
err = pidfs_register_pid(pid);
1989+
if (unlikely(err))
1990+
return err;
1991+
1992+
UNIXCB(skb).pid = get_pid(pid);
19841993
current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
19851994
}
19861995

0 commit comments

Comments
 (0)