From nobody Wed Oct 8 11:45:34 2025 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD244242D94 for ; Sun, 29 Jun 2025 21:45:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751233512; cv=none; b=oDSNr1OGr9qh8UOI6MtOaX4KmAGBlTmnBtHUDWmZ+AhtGIZyHe7gVTXnevBlgyBKym7tjNzyKIwxJ5Xk0jqhxFnF+qH1mQ4jl89xaxHPjyzruesflyeysHoLIYkGqJJtvys9Sepz2tMjGN60UNPE9HznlH+4j/cGZfBig/SCil0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751233512; c=relaxed/simple; bh=NzVgcHKoOIUZwVOYDvnzpsp4Ixb3PiP6jwJB7yn9Lm0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SvxulH06uSHvGXLRXviGTCqJTJUfAEnJgB9+bMdetk7Yi6JUG4AyqLYPMB+DElfhESWHZ6PjNW0t0W4HyqkozvpRkMy+QriDbl/0kwkmhFv9Vy+KbrnlxFUrHJAiuB4427vybda/Cz9Nq1LHsGQTkUCedzyPUGQYFEfuK6HtWNs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=nBafJQyv; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="nBafJQyv" Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 7CC7A3F528 for ; Sun, 29 Jun 2025 21:45:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1751233509; bh=jNbt7oyKjScEoIBZYdPyzN9axx/Wf/C6cCg96ND4tZ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nBafJQyvJ2EEPqdedbVsEUhKkknDbaqvtmOzTvHpf12PHiLFkAm5zVyiTlIZIa1h7 4e9mrq+N4czDaKZw82M8P62Mhv39PVDdtO1CpNrVaqcDT10hujklw+4YtLTDmr5Px1 vf2AaQxdoVM7bqeK2EKgBykKR7aWc46a2H8oImW2Y4a/9FAyWTzi7djytYrlBirzD8 up9hYYVCL6sIvJtxIEUt+/n1fNL2+k5nG3so571PoaFbHH9ZnuOBnMQwA//M+6k/B0 F1QOtJuoJ+66DOHjCaNR6aLGQgRq9m3PhM2CBa4yzn4+U1jO2dEoVvBgVBd86OSQ8g 8GKPRFHAthKCQ== Received: by mail-ed1-f70.google.com with SMTP id 4fb4d7f45d1cf-60c776678edso3448884a12.1 for ; Sun, 29 Jun 2025 14:45:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751233509; x=1751838309; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jNbt7oyKjScEoIBZYdPyzN9axx/Wf/C6cCg96ND4tZ8=; b=wJzn2nEfejKkp0y39W3kJR8uA4YQD77ogg2craRco1DD6gmxoUHtnQHB59snCYj0eW YdxUEHNal9gLXMzOW8bVBXQ48txODRkPmTWsN7FC0fa6CNFQ/t1PTBcuvjEqBaAZ3cQz aZ5mSuXerU4rl2iegv95H0cBp+N6EGmgpRj5JU2CNj7U6R4GMJUXsY9nU1UYVAnLUqxu ejLuCN6Zcpqf12gUrfPxS63md85uMk1HpjmsbU12g9ZN/BmOOtvSKayJ41MkjImU+veA qPCMUMPhuaLAXACBeywQKZx/nMqPk5r3NvXTv08CnbCwzBbafxmVWw0GBVmqa9XVr3QX 4B2w== X-Forwarded-Encrypted: i=1; AJvYcCVcTyuRXC23vF94FEzYK3lpYX0mTGsX8PUM9eH9BQboarDce5iabGKjYUQxZFQ8gRmz7PIm/NSc8meX8yA=@vger.kernel.org X-Gm-Message-State: AOJu0YyecetP2zuJ+a7QWKSo8Dr6tKEuHCRyFBjtyOExGeDuV+cq8nB3 352IjGkNu3FyWBaJJsPOHMHlDISC8aWY6uBFZeYva8tbovh0UXHkTWi5kPhqzMsdBNTRS2KTjs/ XNSvp9es3X7UYC8M5HpW9I1rICvGiWHOFwqCN+nn/qXRQfCqvL7slrAS0ibkUMMG8FN/MTPYcpT ZWlCMiwQ== X-Gm-Gg: ASbGncsrt879Pz0i05kHoIjloUoJke/Qn7pZDSGQBd0IJJiY9RHLrgFbCHG84CURZtu aEy+HQ8UNTnc0MIHBv2p8+8lXeqnBJq4PpztC/WRft4Z9hUx73m6WIBG+zryyoWuiKiG5y3nYbV gm2h6kG5jfZ2vX9JSuny4Ytcw9wEUCF3pOynEPEg0XCpRZMFZ2z+HyBYhTtxg894sYoww9NHHjw PyqTxbTWw9xSupgCNV8hLKXz4aILezzLzXpmioNO8i4qvpeSSyoSHj1JKErafMISDq20szjQD5/ kE6xSh65opaPWXVjtEUNecbK182DAekFvJv8s3KSu/UkHsIhmQ== X-Received: by 2002:a05:6402:50cc:b0:601:d0ec:fea0 with SMTP id 4fb4d7f45d1cf-60c88eb1c90mr9129617a12.5.1751233509016; Sun, 29 Jun 2025 14:45:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE4uKLPcGCI7v0Uifs9eHQmntR5QIGSGL+oic23vZukTBXZ3gZ43gYtsuo5c4s6dBF0o4jh2Q== X-Received: by 2002:a05:6402:50cc:b0:601:d0ec:fea0 with SMTP id 4fb4d7f45d1cf-60c88eb1c90mr9129595a12.5.1751233508641; Sun, 29 Jun 2025 14:45:08 -0700 (PDT) Received: from amikhalitsyn.lan ([178.24.219.243]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-60c828e1a96sm4712037a12.19.2025.06.29.14.45.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Jun 2025 14:45:08 -0700 (PDT) From: Alexander Mikhalitsyn To: kuniyu@google.com Cc: Alexander Mikhalitsyn , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Leon Romanovsky , Arnd Bergmann , Christian Brauner , Lennart Poettering , Luca Boccassi , David Rheinsberg , Kuniyuki Iwashima Subject: [RESEND PATCH net-next 4/6] af_unix: stash pidfs dentry when needed Date: Sun, 29 Jun 2025 23:44:41 +0200 Message-ID: <20250629214449.14462-5-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250629214449.14462-1-aleksandr.mikhalitsyn@canonical.com> References: <20250629214449.14462-1-aleksandr.mikhalitsyn@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Simon Horman Cc: Leon Romanovsky Cc: Arnd Bergmann Cc: Christian Brauner Cc: Kuniyuki Iwashima Cc: Lennart Poettering Cc: Luca Boccassi Cc: David Rheinsberg Signed-off-by: Alexander Mikhalitsyn --- include/net/scm.h | 35 ++++++++++++++++++++++++++++++----- net/unix/af_unix.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/include/net/scm.h b/include/net/scm.h index 856eb3a380f6..d1ae0704f230 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -66,19 +67,37 @@ static __inline__ void unix_get_peersec_dgram(struct so= cket *sock, struct scm_co { } #endif /* CONFIG_SECURITY_NETWORK */ =20 -static __inline__ void scm_set_cred(struct scm_cookie *scm, - struct pid *pid, kuid_t uid, kgid_t gid) +static __inline__ int __scm_set_cred(struct scm_cookie *scm, + struct pid *pid, bool pidfs_register, + kuid_t uid, kgid_t gid) { - scm->pid =3D get_pid(pid); + if (pidfs_register) { + int err; + + err =3D pidfs_register_pid(pid); + if (err) + return err; + } + + scm->pid =3D get_pid(pid); + scm->creds.pid =3D pid_vnr(pid); scm->creds.uid =3D uid; scm->creds.gid =3D gid; + return 0; +} + +static __inline__ void scm_set_cred(struct scm_cookie *scm, + struct pid *pid, kuid_t uid, kgid_t gid) +{ + /* __scm_set_cred() can't fail when pidfs_register =3D=3D false */ + (void) __scm_set_cred(scm, pid, false, uid, gid); } =20 static __inline__ void scm_destroy_cred(struct scm_cookie *scm) { put_pid(scm->pid); - scm->pid =3D NULL; + scm->pid =3D NULL; } =20 static __inline__ void scm_destroy(struct scm_cookie *scm) @@ -90,9 +109,15 @@ static __inline__ void scm_destroy(struct scm_cookie *s= cm) =20 static __inline__ int __scm_replace_pid(struct scm_cookie *scm, struct pid= *pid) { + int err; + /* drop all previous references */ scm_destroy_cred(scm); =20 + err =3D pidfs_register_pid(pid); + if (err) + return err; + scm->pid =3D get_pid(pid); scm->creds.pid =3D pid_vnr(pid); return 0; @@ -105,7 +130,7 @@ static __inline__ int scm_send(struct socket *sock, str= uct msghdr *msg, scm->creds.uid =3D INVALID_UID; scm->creds.gid =3D INVALID_GID; if (forcecreds) - scm_set_cred(scm, task_tgid(current), current_uid(), current_gid()); + __scm_set_cred(scm, task_tgid(current), true, current_uid(), current_gid= ()); unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <=3D 0) return 0; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5efe6e44abdf..1f4a5fe8a1f7 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1924,12 +1924,34 @@ static void unix_peek_fds(struct scm_cookie *scm, s= truct sk_buff *skb) scm->fp =3D scm_fp_dup(UNIXCB(skb).fp); } =20 +static int __skb_set_pid(struct sk_buff *skb, struct pid *pid, bool pidfs_= register) +{ + if (pidfs_register) { + int err; + + err =3D pidfs_register_pid(pid); + if (err) + return err; + } + + UNIXCB(skb).pid =3D get_pid(pid); + return 0; +} + static void unix_destruct_scm(struct sk_buff *skb) { struct scm_cookie scm; =20 memset(&scm, 0, sizeof(scm)); - scm.pid =3D UNIXCB(skb).pid; + + /* Pass ownership of struct pid from skb to scm cookie. + * + * We rely on scm_destroy() -> scm_destroy_cred() to properly + * release everything. + */ + scm.pid =3D UNIXCB(skb).pid; + UNIXCB(skb).pid =3D NULL; + if (UNIXCB(skb).fp) unix_detach_fds(&scm, skb); =20 @@ -1943,7 +1965,10 @@ static int unix_scm_to_skb(struct scm_cookie *scm, s= truct sk_buff *skb, bool sen { int err =3D 0; =20 - UNIXCB(skb).pid =3D get_pid(scm->pid); + err =3D __skb_set_pid(skb, scm->pid, false); + if (unlikely(err)) + return err; + UNIXCB(skb).uid =3D scm->creds.uid; UNIXCB(skb).gid =3D scm->creds.gid; UNIXCB(skb).fp =3D NULL; @@ -1976,7 +2001,12 @@ static int unix_maybe_add_creds(struct sk_buff *skb,= const struct sock *sk, return 0; =20 if (unix_may_passcred(sk) || unix_may_passcred(other)) { - UNIXCB(skb).pid =3D get_pid(task_tgid(current)); + int err; + + err =3D __skb_set_pid(skb, task_tgid(current), true); + if (unlikely(err)) + return err; + current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); } =20 --=20 2.43.0