mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
more pidref'ification (#35839)
This is split out of #35264, but makes a ton of sense on its own.
This commit is contained in:
@@ -839,6 +839,8 @@ int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret_
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
r = cg_pid_get_path(controller, pidref->pid, &path);
|
||||
if (r < 0)
|
||||
@@ -1204,6 +1206,8 @@ int cg_pidref_get_unit(const PidRef *pidref, char **ret) {
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
r = cg_pid_get_unit(pidref->pid, &unit);
|
||||
if (r < 0)
|
||||
@@ -1402,6 +1406,28 @@ int cg_pid_get_session(pid_t pid, char **ret_session) {
|
||||
return cg_path_get_session(cgroup, ret_session);
|
||||
}
|
||||
|
||||
int cg_pidref_get_session(const PidRef *pidref, char **ret) {
|
||||
int r;
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
_cleanup_free_ char *session = NULL;
|
||||
r = cg_pid_get_session(pidref->pid, &session);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = pidref_verify(pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_path_get_owner_uid(const char *path, uid_t *ret_uid) {
|
||||
_cleanup_free_ char *slice = NULL;
|
||||
char *start, *end;
|
||||
@@ -1439,6 +1465,29 @@ int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid) {
|
||||
return cg_path_get_owner_uid(cgroup, ret_uid);
|
||||
}
|
||||
|
||||
int cg_pidref_get_owner_uid(const PidRef *pidref, uid_t *ret) {
|
||||
int r;
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
uid_t uid;
|
||||
r = cg_pid_get_owner_uid(pidref->pid, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = pidref_verify(pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret)
|
||||
*ret = uid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_path_get_slice(const char *p, char **ret_slice) {
|
||||
const char *e = NULL;
|
||||
|
||||
|
||||
@@ -286,7 +286,9 @@ int cg_shift_path(const char *cgroup, const char *cached_root, const char **ret_
|
||||
int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **ret_cgroup);
|
||||
|
||||
int cg_pid_get_session(pid_t pid, char **ret_session);
|
||||
int cg_pidref_get_session(const PidRef *pidref, char **ret);
|
||||
int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid);
|
||||
int cg_pidref_get_owner_uid(const PidRef *pidref, uid_t *ret);
|
||||
int cg_pid_get_unit(pid_t pid, char **ret_unit);
|
||||
int cg_pidref_get_unit(const PidRef *pidref, char **ret);
|
||||
int cg_pid_get_user_unit(pid_t pid, char **ret_unit);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -334,46 +334,46 @@ _public_ int sd_pidfd_get_cgroup(int pidfd, char **ret_cgroup) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_peer_get_session(int fd, char **session) {
|
||||
struct ucred ucred = UCRED_INVALID;
|
||||
_public_ int sd_peer_get_session(int fd, char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(fd >= 0, -EBADF);
|
||||
assert_return(session, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = getpeercred(fd, &ucred);
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
r = getpeerpidref(fd, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cg_pid_get_session(ucred.pid, session);
|
||||
return cg_pidref_get_session(&pidref, ret);
|
||||
}
|
||||
|
||||
_public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
|
||||
struct ucred ucred;
|
||||
_public_ int sd_peer_get_owner_uid(int fd, uid_t *ret) {
|
||||
int r;
|
||||
|
||||
assert_return(fd >= 0, -EBADF);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = getpeercred(fd, &ucred);
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
r = getpeerpidref(fd, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cg_pid_get_owner_uid(ucred.pid, uid);
|
||||
return cg_pidref_get_owner_uid(&pidref, ret);
|
||||
}
|
||||
|
||||
_public_ int sd_peer_get_unit(int fd, char **unit) {
|
||||
struct ucred ucred;
|
||||
_public_ int sd_peer_get_unit(int fd, char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(fd >= 0, -EBADF);
|
||||
assert_return(unit, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = getpeercred(fd, &ucred);
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
r = getpeerpidref(fd, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cg_pid_get_unit(ucred.pid, unit);
|
||||
return cg_pidref_get_unit(&pidref, ret);
|
||||
}
|
||||
|
||||
_public_ int sd_peer_get_user_unit(int fd, char **unit) {
|
||||
|
||||
@@ -210,11 +210,11 @@ TEST(proc) {
|
||||
if (pidref_is_kernel_thread(&pid) != 0)
|
||||
continue;
|
||||
|
||||
cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid.pid, &path);
|
||||
cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, &pid, &path);
|
||||
cg_pid_get_path_shifted(pid.pid, NULL, &path_shifted);
|
||||
cg_pid_get_owner_uid(pid.pid, &uid);
|
||||
cg_pid_get_session(pid.pid, &session);
|
||||
cg_pid_get_unit(pid.pid, &unit);
|
||||
cg_pidref_get_owner_uid(&pid, &uid);
|
||||
cg_pidref_get_session(&pid, &session);
|
||||
cg_pidref_get_unit(&pid, &unit);
|
||||
cg_pid_get_user_unit(pid.pid, &user_unit);
|
||||
cg_pid_get_machine_name(pid.pid, &machine);
|
||||
cg_pid_get_slice(pid.pid, &slice);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user