journald: make journal Varlink IPC accessible to unpriv clients

The Synchronize() function is just too useful for clients, so that we
can make "systemd-run -v --user" actually useful. Hence let's make the
socket accessible without privs. Deny most method calls however, except
for the Synchronize() call.
This commit is contained in:
Lennart Poettering
2025-03-26 12:35:43 -04:00
parent 0aaae3eb3d
commit a388f007e0
3 changed files with 34 additions and 7 deletions

View File

@@ -46,8 +46,23 @@ static int vl_method_synchronize(sd_varlink *link, sd_json_variant *parameters,
if (r != 0)
return r;
log_full(offline != 0 ? LOG_INFO : LOG_DEBUG,
"Received client request to sync journal (%s offlining).", offline != 0 ? "with" : "without");
if (offline > 0) {
/* Do not allow unprivileged clients to offline the journal files, since that's potentially slow */
r = varlink_check_privileged_peer(link);
if (r < 0)
return r;
} else if (offline < 0) {
uid_t uid = 0;
r = sd_varlink_get_peer_uid(link, &uid);
if (r < 0)
return r;
offline = uid == 0; /* for compat, if not specified default to offlining, except for non-root */
}
log_full(offline ? LOG_INFO : LOG_DEBUG,
"Received client request to sync journal (%s offlining).", offline ? "with" : "without");
_cleanup_(sync_req_freep) SyncReq *sr = NULL;
@@ -55,7 +70,7 @@ static int vl_method_synchronize(sd_varlink *link, sd_json_variant *parameters,
if (r < 0)
return r;
sr->offline = offline != 0;
sr->offline = offline;
sd_varlink_set_userdata(link, sr);
sync_req_revalidate(TAKE_PTR(sr));
@@ -72,6 +87,10 @@ static int vl_method_rotate(sd_varlink *link, sd_json_variant *parameters, sd_va
if (r != 0)
return r;
r = varlink_check_privileged_peer(link);
if (r < 0)
return r;
log_info("Received client request to rotate journal, rotating.");
server_full_rotate(s);
@@ -88,6 +107,10 @@ static int vl_method_flush_to_var(sd_varlink *link, sd_json_variant *parameters,
if (r != 0)
return r;
r = varlink_check_privileged_peer(link);
if (r < 0)
return r;
if (s->namespace)
return sd_varlink_error(link, "io.systemd.Journal.NotSupportedByNamespaces", NULL);
@@ -107,6 +130,10 @@ static int vl_method_relinquish_var(sd_varlink *link, sd_json_variant *parameter
if (r != 0)
return r;
r = varlink_check_privileged_peer(link);
if (r < 0)
return r;
if (s->namespace)
return sd_varlink_error(link, "io.systemd.Journal.NotSupportedByNamespaces", NULL);
@@ -152,7 +179,7 @@ int server_open_varlink(Server *s, const char *socket, int fd) {
r = varlink_server_new(
&s->varlink_server,
SD_VARLINK_SERVER_ROOT_ONLY|SD_VARLINK_SERVER_INHERIT_USERDATA,
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA,
s);
if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m");
@@ -185,7 +212,7 @@ int server_open_varlink(Server *s, const char *socket, int fd) {
return r;
if (fd < 0)
r = sd_varlink_server_listen_address(s->varlink_server, socket, 0600);
r = sd_varlink_server_listen_address(s->varlink_server, socket, 0666);
else
r = sd_varlink_server_listen_fd(s->varlink_server, fd);
if (r < 0)

View File

@@ -5,7 +5,7 @@
static SD_VARLINK_DEFINE_METHOD(
Synchronize,
SD_VARLINK_FIELD_COMMENT("Controls whether to offline the journal files as part of the synchronization operation."),
SD_VARLINK_DEFINE_INPUT(offline, SD_VARLINK_BOOL, 0));
SD_VARLINK_DEFINE_INPUT(offline, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD(Rotate);
static SD_VARLINK_DEFINE_METHOD(FlushToVar);

View File

@@ -15,4 +15,4 @@ StopWhenUnneeded=yes
[Socket]
Service=systemd-journald@%i.service
ListenStream=/run/systemd/journal.%i/io.systemd.journal
SocketMode=0600
SocketMode=0666