linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Kuniyuki Iwashima <kuniyu@amazon.com>,
	linux-fsdevel@vger.kernel.org,  Jann Horn <jannh@google.com>
Cc: "Eric Dumazet" <edumazet@google.com>,
	"Oleg Nesterov" <oleg@redhat.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"Daan De Meyer" <daan.j.demeyer@gmail.com>,
	"David Rheinsberg" <david@readahead.eu>,
	"Jakub Kicinski" <kuba@kernel.org>, "Jan Kara" <jack@suse.cz>,
	"Lennart Poettering" <lennart@poettering.net>,
	"Luca Boccassi" <bluca@debian.org>, "Mike Yuan" <me@yhndnzj.com>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Simon Horman" <horms@kernel.org>,
	"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	"Christian Brauner" <brauner@kernel.org>,
	"Alexander Mikhalitsyn" <alexander@mihalicyn.com>
Subject: [PATCH v4 09/11] pidfs, coredump: allow to verify coredump connection
Date: Wed, 07 May 2025 18:13:42 +0200	[thread overview]
Message-ID: <20250507-work-coredump-socket-v4-9-af0ef317b2d0@kernel.org> (raw)
In-Reply-To: <20250507-work-coredump-socket-v4-0-af0ef317b2d0@kernel.org>

When a coredump connection is initiated use the socket cookie as the
coredump cookie and store it in the pidfd. The receiver can now easily
authenticate that the connection is coming from the kernel.

Unless the coredump server expects to handle connection from
non-crashing task it can validate that the connection has been made from
a crashing task:

   fd_coredump = accept4(fd_socket, NULL, NULL, SOCK_CLOEXEC);
   getsockopt(fd_coredump, SOL_SOCKET, SO_PEERPIDFD, &fd_peer_pidfd, &fd_peer_pidfd_len);

   struct pidfd_info info = {
           info.mask = PIDFD_INFO_EXIT | PIDFD_INFO_COREDUMP,
   };

   ioctl(pidfd, PIDFD_GET_INFO, &info);
   /* Refuse connections that aren't from a crashing task. */
   if (!(info.mask & PIDFD_INFO_COREDUMP) || !(info.coredump_mask & PIDFD_COREDUMPED) )
           close(fd_coredump);

   /*
    * Make sure that the coredump cookie matches the connection cookie.
    * If they don't it's not the coredump connection from the kernel.
    * We'll get another connection request in a bit.
    */
   getsocketop(fd_coredump, SOL_SOCKET, SO_COOKIE, &peer_cookie, &peer_cookie_len);
   if (!info.coredump_cookie || (info.coredump_cookie != peer_cookie))
           close(fd_coredump);

The kernel guarantees that by the time the connection is made the
coredump info is available.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/coredump.c              |  3 ++-
 fs/pidfs.c                 | 20 +++++++++++++++++++-
 include/linux/net.h        |  1 +
 include/linux/pidfs.h      |  1 +
 include/uapi/linux/pidfd.h |  1 +
 net/unix/af_unix.c         |  7 +++++++
 6 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/fs/coredump.c b/fs/coredump.c
index ddff1854988f..cfb7a3459785 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -907,7 +907,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 		 */
 		retval = kernel_connect(socket,
 					(struct sockaddr *)(&coredump_unix_socket),
-					COREDUMP_UNIX_SOCKET_ADDR_SIZE, O_NONBLOCK);
+					COREDUMP_UNIX_SOCKET_ADDR_SIZE, O_NONBLOCK |
+					SOCK_COREDUMP);
 
 		/*
 		 * ... So we can safely put our pidfs reference now...
diff --git a/fs/pidfs.c b/fs/pidfs.c
index 8c4d83fb115b..7ff1e7923f19 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -35,6 +35,7 @@ struct pidfs_exit_info {
 	__u64 cgroupid;
 	__s32 exit_code;
 	__u32 coredump_mask;
+	__u64 coredump_cookie;
 };
 
 struct pidfs_inode {
@@ -300,6 +301,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
 
 	if (mask & PIDFD_INFO_COREDUMP) {
 		kinfo.mask |= PIDFD_INFO_COREDUMP;
+		kinfo.coredump_cookie = READ_ONCE(pidfs_i(inode)->__pei.coredump_cookie);
 		kinfo.coredump_mask = READ_ONCE(pidfs_i(inode)->__pei.coredump_mask);
 	}
 
@@ -321,8 +323,10 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
 
 	if (!(kinfo.mask & PIDFD_INFO_COREDUMP)) {
 		task_lock(task);
-		if (task->mm)
+		if (task->mm) {
+			kinfo.coredump_cookie = READ_ONCE(pidfs_i(inode)->__pei.coredump_cookie);
 			kinfo.coredump_mask = pidfs_coredump_mask(task->mm->flags);
+		}
 		task_unlock(task);
 	}
 
@@ -589,6 +593,20 @@ void pidfs_exit(struct task_struct *tsk)
 	}
 }
 
+void pidfs_coredump_cookie(struct pid *pid, u64 coredump_cookie)
+{
+	struct pidfs_exit_info *exit_info;
+	struct dentry *dentry = pid->stashed;
+	struct inode *inode;
+
+	if (WARN_ON_ONCE(!dentry))
+		return;
+
+	inode = d_inode(dentry);
+	exit_info = &pidfs_i(inode)->__pei;
+	smp_store_release(&exit_info->coredump_cookie, coredump_cookie);
+}
+
 void pidfs_coredump(const struct coredump_params *cprm)
 {
 	struct pid *pid = cprm->pid;
diff --git a/include/linux/net.h b/include/linux/net.h
index 0ff950eecc6b..005f1e52e7f1 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -81,6 +81,7 @@ enum sock_type {
 #ifndef SOCK_NONBLOCK
 #define SOCK_NONBLOCK	O_NONBLOCK
 #endif
+#define SOCK_COREDUMP	O_TRUNC
 
 #endif /* ARCH_HAS_SOCKET_TYPES */
 
diff --git a/include/linux/pidfs.h b/include/linux/pidfs.h
index f7729b9371bc..5875037be272 100644
--- a/include/linux/pidfs.h
+++ b/include/linux/pidfs.h
@@ -10,6 +10,7 @@ void pidfs_add_pid(struct pid *pid);
 void pidfs_remove_pid(struct pid *pid);
 void pidfs_exit(struct task_struct *tsk);
 void pidfs_coredump(const struct coredump_params *cprm);
+void pidfs_coredump_cookie(struct pid *pid, u64 coredump_cookie);
 extern const struct dentry_operations pidfs_dentry_operations;
 int pidfs_register_pid(struct pid *pid);
 void pidfs_get_pid(struct pid *pid);
diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h
index 84ac709f560c..f46819a02d23 100644
--- a/include/uapi/linux/pidfd.h
+++ b/include/uapi/linux/pidfd.h
@@ -108,6 +108,7 @@ struct pidfd_info {
 	__s32 exit_code;
 	__u32 coredump_mask;
 	__u32 __spare1;
+	__u64 coredump_cookie;
 };
 
 #define PIDFS_IOCTL_MAGIC 0xFF
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 148d008862e7..45e7a6363939 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -101,6 +101,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/pidfs.h>
+#include <linux/sock_diag.h>
 #include <net/af_unix.h>
 #include <net/net_namespace.h>
 #include <net/scm.h>
@@ -771,6 +772,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
 
 struct unix_peercred {
 	struct pid *peer_pid;
+	u64 cookie;
 	const struct cred *peer_cred;
 };
 
@@ -806,6 +808,8 @@ static void drop_peercred(struct unix_peercred *peercred)
 static inline void init_peercred(struct sock *sk,
 				 const struct unix_peercred *peercred)
 {
+	if (peercred->cookie)
+		pidfs_coredump_cookie(peercred->peer_pid, peercred->cookie);
 	sk->sk_peer_pid = peercred->peer_pid;
 	sk->sk_peer_cred = peercred->peer_cred;
 }
@@ -1717,6 +1721,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	unix_peer(newsk)	= sk;
 	newsk->sk_state		= TCP_ESTABLISHED;
 	newsk->sk_type		= sk->sk_type;
+	/* Prepare a new socket cookie for the receiver. */
+	if (flags & SOCK_COREDUMP)
+		peercred.cookie = sock_gen_cookie(newsk);
 	init_peercred(newsk, &peercred);
 	newu = unix_sk(newsk);
 	newu->listener = other;

-- 
2.47.2


  parent reply	other threads:[~2025-05-07 16:14 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-07 16:13 [PATCH v4 00/11] coredump: add coredump socket Christian Brauner
2025-05-07 16:13 ` [PATCH v4 01/11] coredump: massage format_corname() Christian Brauner
2025-05-07 16:13 ` [PATCH v4 02/11] coredump: massage do_coredump() Christian Brauner
2025-05-07 16:13 ` [PATCH v4 03/11] coredump: reflow dump helpers a little Christian Brauner
2025-05-07 16:13 ` [PATCH v4 04/11] net: reserve prefix Christian Brauner
2025-05-07 22:45   ` Kuniyuki Iwashima
2025-05-08  6:16     ` Christian Brauner
2025-05-08 21:47       ` Kuniyuki Iwashima
2025-05-09  5:54         ` Christian Brauner
2025-05-09  8:07           ` Daniel Borkmann
2025-05-07 16:13 ` [PATCH v4 05/11] coredump: add coredump socket Christian Brauner
2025-05-07 16:13 ` [PATCH v4 06/11] coredump: validate socket name as it is written Christian Brauner
2025-05-07 16:13 ` [PATCH v4 07/11] coredump: show supported coredump modes Christian Brauner
2025-05-07 16:13 ` [PATCH v4 08/11] pidfs, coredump: add PIDFD_INFO_COREDUMP Christian Brauner
2025-05-07 16:13 ` Christian Brauner [this message]
2025-05-07 18:34   ` [PATCH v4 09/11] pidfs, coredump: allow to verify coredump connection Mickaël Salaün
2025-05-07 16:13 ` [PATCH v4 10/11] selftests/pidfd: add PIDFD_INFO_COREDUMP infrastructure Christian Brauner
2025-05-07 16:13 ` [PATCH v4 11/11] selftests/coredump: add tests for AF_UNIX coredumps Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250507-work-coredump-socket-v4-9-af0ef317b2d0@kernel.org \
    --to=brauner@kernel.org \
    --cc=alexander@mihalicyn.com \
    --cc=bluca@debian.org \
    --cc=daan.j.demeyer@gmail.com \
    --cc=davem@davemloft.net \
    --cc=david@readahead.eu \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@amazon.com \
    --cc=lennart@poettering.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=me@yhndnzj.com \
    --cc=netdev@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=pabeni@redhat.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zbyszek@in.waw.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).