From: Lennart Poettering Date: Thu, 25 Apr 2024 08:55:23 +0000 (+0200) Subject: varlink: add new call varlink_server_add_connection_pair() for two-fd servers X-Git-Tag: v257-rc1~1037^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e73ae07b529d499c976f34903b62936999dfc355;p=thirdparty%2Fsystemd.git varlink: add new call varlink_server_add_connection_pair() for two-fd servers This adds the server-side for varlink connections over two distinct fds. --- diff --git a/src/shared/varlink.c b/src/shared/varlink.c index fea330b86de..563e81472a4 100644 --- a/src/shared/varlink.c +++ b/src/shared/varlink.c @@ -3464,19 +3464,34 @@ static int count_connection(VarlinkServer *server, const struct ucred *ucred) { return 0; } -int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) { +int varlink_server_add_connection_pair( + VarlinkServer *server, + int input_fd, + int output_fd, + const struct ucred *override_ucred, + Varlink **ret) { + _cleanup_(varlink_unrefp) Varlink *v = NULL; struct ucred ucred = UCRED_INVALID; bool ucred_acquired; int r; assert_return(server, -EINVAL); - assert_return(fd >= 0, -EBADF); + assert_return(input_fd >= 0, -EBADF); + assert_return(output_fd >= 0, -EBADF); if ((server->flags & (VARLINK_SERVER_ROOT_ONLY|VARLINK_SERVER_ACCOUNT_UID)) != 0) { - r = getpeercred(fd, &ucred); - if (r < 0) - return varlink_server_log_errno(server, r, "Failed to acquire peer credentials of incoming socket, refusing: %m"); + + if (override_ucred) + ucred = *override_ucred; + else { + if (input_fd != output_fd) + return varlink_server_log_errno(server, SYNTHETIC_ERRNO(EOPNOTSUPP), "Cannot determine peer identity of connection with separate input/output, refusing: %m"); + + r = getpeercred(input_fd, &ucred); + if (r < 0) + return varlink_server_log_errno(server, r, "Failed to acquire peer credentials of incoming socket, refusing: %m"); + } ucred_acquired = true; @@ -3496,7 +3511,8 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) if (r < 0) return r; - v->input_fd = v->output_fd = fd; + v->input_fd = input_fd; + v->output_fd = output_fd; if (server->flags & VARLINK_SERVER_INHERIT_USERDATA) v->userdata = server->userdata; @@ -3506,7 +3522,7 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) } _cleanup_free_ char *desc = NULL; - if (asprintf(&desc, "%s-%i", varlink_server_description(server), fd) >= 0) + if (asprintf(&desc, "%s-%i-%i", varlink_server_description(server), input_fd, output_fd) >= 0) v->description = TAKE_PTR(desc); /* Link up the server and the connection, and take reference in both directions. Note that the @@ -3534,6 +3550,10 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) return 0; } +int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) { + return varlink_server_add_connection_pair(server, fd, fd, /* override_ucred= */ NULL, ret); +} + static VarlinkServerSocket *varlink_server_socket_free(VarlinkServerSocket *ss) { if (!ss) return NULL; diff --git a/src/shared/varlink.h b/src/shared/varlink.h index 1ae65424b1e..2585c45efd6 100644 --- a/src/shared/varlink.h +++ b/src/shared/varlink.h @@ -221,6 +221,7 @@ int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t int varlink_server_listen_fd(VarlinkServer *s, int fd); int varlink_server_listen_auto(VarlinkServer *s); int varlink_server_add_connection(VarlinkServer *s, int fd, Varlink **ret); +int varlink_server_add_connection_pair(VarlinkServer *s, int input_fd, int output_fd, const struct ucred *ucred_override, Varlink **ret); /* Bind callbacks */ int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMethod callback);