diff --git a/src/net/SocketDescriptor.cxx b/src/net/SocketDescriptor.cxx
index 4752b7e14..6ffb5de53 100644
--- a/src/net/SocketDescriptor.cxx
+++ b/src/net/SocketDescriptor.cxx
@@ -8,6 +8,10 @@
 #include "IPv6Address.hxx"
 #include "UniqueSocketDescriptor.hxx"
 
+#ifdef __linux__
+#include "io/UniqueFileDescriptor.hxx"
+#endif
+
 #ifdef _WIN32
 #include <ws2tcpip.h>
 #else
@@ -235,6 +239,24 @@ SocketDescriptor::GetPeerCredentials() const noexcept
 
 #endif
 
+#ifdef __linux__
+
+#ifndef SO_PEERPIDFD
+#define SO_PEERPIDFD 77
+#endif
+
+UniqueFileDescriptor
+SocketDescriptor::GetPeerPidfd() const noexcept
+{
+	int pidfd;
+	if (GetOption(SOL_SOCKET, SO_PEERPIDFD, &pidfd, sizeof(pidfd)) < sizeof(pidfd))
+		return {};
+
+	return UniqueFileDescriptor{pidfd};
+}
+
+#endif // __linux__
+
 #ifdef _WIN32
 
 bool
diff --git a/src/net/SocketDescriptor.hxx b/src/net/SocketDescriptor.hxx
index 1b2f0c01d..1f0621c68 100644
--- a/src/net/SocketDescriptor.hxx
+++ b/src/net/SocketDescriptor.hxx
@@ -25,6 +25,7 @@ class StaticSocketAddress;
 class IPv4Address;
 class IPv6Address;
 class UniqueSocketDescriptor;
+class UniqueFileDescriptor;
 
 /**
  * An OO wrapper for a Berkeley or WinSock socket descriptor.
@@ -229,6 +230,16 @@ public:
 	struct ucred GetPeerCredentials() const noexcept;
 #endif
 
+#ifdef __linux__
+	/**
+	 * Get a pidfd for the peer process.  Returns an undefined
+	 * instance on error (with errno set).
+	 *
+	 * Requires Linux 6.5.
+	 */
+	UniqueFileDescriptor GetPeerPidfd() const noexcept;
+#endif // __linux__
+
 	bool SetOption(int level, int name,
 		       const void *value, std::size_t size) const noexcept;