From a7d58b7d3d304de2790b60e7ed4625b1477670db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Mar 2025 12:34:34 -0400 Subject: [PATCH] varlink: add common helper that refuse method calls from unpriv clients --- src/libsystemd/sd-varlink/varlink-util.c | 16 ++++++++++++++++ src/libsystemd/sd-varlink/varlink-util.h | 2 ++ src/login/logind-varlink.c | 7 ++----- src/nsresourced/nsresourcework.c | 5 +---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libsystemd/sd-varlink/varlink-util.c b/src/libsystemd/sd-varlink/varlink-util.c index 899b8ea929f..18adf93a59f 100644 --- a/src/libsystemd/sd-varlink/varlink-util.c +++ b/src/libsystemd/sd-varlink/varlink-util.c @@ -181,3 +181,19 @@ int varlink_server_new( *ret = TAKE_PTR(s); return 0; } + +int varlink_check_privileged_peer(sd_varlink *vl) { + int r; + + assert(vl); + + uid_t uid; + r = sd_varlink_get_peer_uid(vl, &uid); + if (r < 0) + return log_debug_errno(r, "Failed to get peer UID: %m"); + + if (uid != 0) + return sd_varlink_error(vl, SD_VARLINK_ERROR_PERMISSION_DENIED, /* parameters= */ NULL); + + return 0; +} diff --git a/src/libsystemd/sd-varlink/varlink-util.h b/src/libsystemd/sd-varlink/varlink-util.h index 124b16263e8..449b9627670 100644 --- a/src/libsystemd/sd-varlink/varlink-util.h +++ b/src/libsystemd/sd-varlink/varlink-util.h @@ -26,3 +26,5 @@ int varlink_server_new( sd_varlink_server **ret, sd_varlink_server_flags_t flags, void *userdata); + +int varlink_check_privileged_peer(sd_varlink *vl); diff --git a/src/login/logind-varlink.c b/src/login/logind-varlink.c index 23262fb9a5b..83f0c55531c 100644 --- a/src/login/logind-varlink.c +++ b/src/login/logind-varlink.c @@ -241,12 +241,9 @@ static int vl_method_create_session(sd_varlink *link, sd_json_variant *parameter p.remote = p.remote_user || p.remote_host; /* Before we continue processing this, let's ensure the peer is privileged */ - uid_t peer_uid; - r = sd_varlink_get_peer_uid(link, &peer_uid); + r = varlink_check_privileged_peer(link); if (r < 0) - return log_debug_errno(r, "Failed to get peer UID: %m"); - if (peer_uid != 0) - return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, /* parameters= */ NULL); + return r; if (!pidref_is_set(&p.pid)) { r = varlink_get_peer_pidref(link, &p.pid); diff --git a/src/nsresourced/nsresourcework.c b/src/nsresourced/nsresourcework.c index 671afc69977..0e23ebeec7f 100644 --- a/src/nsresourced/nsresourcework.c +++ b/src/nsresourced/nsresourcework.c @@ -1197,7 +1197,6 @@ static int vl_method_add_mount_to_user_namespace(sd_varlink *link, sd_json_varia }; int r, mnt_id = 0; struct stat userns_st; - uid_t peer_uid; assert(link); assert(parameters); @@ -1207,11 +1206,9 @@ static int vl_method_add_mount_to_user_namespace(sd_varlink *link, sd_json_varia return r; /* Allowlisting arbitrary mounts is a privileged operation */ - r = sd_varlink_get_peer_uid(link, &peer_uid); + r = varlink_check_privileged_peer(link); if (r < 0) return r; - if (peer_uid != 0) - return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL); r = sd_varlink_dispatch(link, parameters, parameter_dispatch_table, &p); if (r != 0) -- 2.47.3