From b2206fe514d1ef3b917f2e5b64d9d1e5fad3e408 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 Nov 2024 16:35:48 +0100 Subject: [PATCH] socket-util: introduce getpeerpidref() This combines getpeercred() and getpeerpidfd() and returns a PidRef --- src/basic/socket-util.c | 22 ++++++++++++++++++++++ src/basic/socket-util.h | 2 ++ src/test/test-socket-util.c | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 94089323b45..9190072f4e2 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -975,6 +975,28 @@ int getpeerpidfd(int fd) { return pidfd; } +int getpeerpidref(int fd, PidRef *ret) { + int r; + + assert(fd >= 0); + assert(ret); + + int pidfd = getpeerpidfd(fd); + if (pidfd < 0) { + if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd)) + return pidfd; + + struct ucred ucred; + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return pidref_set_pid(ret, ucred.pid); + } + + return pidref_set_pidfd_consume(ret, pidfd); +} + ssize_t send_many_fds_iov_sa( int transport_fd, int *fds_array, size_t n_fds_array, diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 874e559a4b3..e21a4427f0d 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -20,6 +20,7 @@ #include "macro.h" #include "missing_network.h" #include "missing_socket.h" +#include "pidref.h" #include "sparse-endian.h" union sockaddr_union { @@ -154,6 +155,7 @@ int getpeercred(int fd, struct ucred *ucred); int getpeersec(int fd, char **ret); int getpeergroups(int fd, gid_t **ret); int getpeerpidfd(int fd); +int getpeerpidref(int fd, PidRef *ret); ssize_t send_many_fds_iov_sa( int transport_fd, diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index f7b31aeb46f..63bbb1d1d27 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -584,4 +584,25 @@ TEST(sockaddr_un_set_path) { assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) >= 0); } +TEST(getpeerpidref) { + _cleanup_close_pair_ int fd[2] = EBADF_PAIR; + + ASSERT_OK(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fd)); + + _cleanup_(pidref_done) PidRef pidref0 = PIDREF_NULL, pidref1 = PIDREF_NULL, pidref_self = PIDREF_NULL, pidref_pid1 = PIDREF_NULL; + ASSERT_OK(getpeerpidref(fd[0], &pidref0)); + ASSERT_OK(getpeerpidref(fd[1], &pidref1)); + + ASSERT_OK(pidref_set_self(&pidref_self)); + ASSERT_OK(pidref_set_pid(&pidref_pid1, 1)); + + ASSERT_TRUE(pidref_equal(&pidref0, &pidref1)); + ASSERT_TRUE(pidref_equal(&pidref0, &pidref_self)); + ASSERT_TRUE(pidref_equal(&pidref1, &pidref_self)); + + ASSERT_TRUE(!pidref_equal(&pidref_self, &pidref_pid1)); + ASSERT_TRUE(!pidref_equal(&pidref1, &pidref_pid1)); + ASSERT_TRUE(!pidref_equal(&pidref0, &pidref_pid1)); +} + DEFINE_TEST_MAIN(LOG_DEBUG); -- 2.47.3