From: Lennart Poettering Date: Mon, 19 May 2025 09:56:28 +0000 (+0200) Subject: logind: fix escaping of various fields in state files X-Git-Tag: v258-rc1~529^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=232f4e12fe526bfbcd5c7bd857bbb6a0db818cbc;p=thirdparty%2Fsystemd.git logind: fix escaping of various fields in state files parse_env_file() applies a certain kind of unescaping, and we really need to match that when writing out arbitrary strings. (This gets a bit confusing in the inhibit case, since that already applied one level of escaping on its own...) --- diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index c8ba63ddfa6..22526ac0bf8 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -117,28 +117,19 @@ static int inhibitor_save(Inhibitor *i) { i->uid, i->pid.pid); - if (i->who) { - _cleanup_free_ char *cc = NULL; - - cc = cescape(i->who); - if (!cc) - return log_oom(); - - fprintf(f, "WHO=%s\n", cc); - } - - if (i->why) { - _cleanup_free_ char *cc = NULL; - - cc = cescape(i->why); - if (!cc) - return log_oom(); - - fprintf(f, "WHY=%s\n", cc); - } - - if (i->fifo_path) - fprintf(f, "FIFO=%s\n", i->fifo_path); + /* For historical reasons there's double escaping applied here: once here via cescape(), and once by + * env_file_fputs_assignment() */ + _cleanup_free_ char *who_escaped = cescape(i->who); + if (!who_escaped) + return log_oom(); + env_file_fputs_assignment(f, "WHO=", who_escaped); + + _cleanup_free_ char *why_escaped = cescape(i->why); + if (!why_escaped) + return log_oom(); + env_file_fputs_assignment(f, "WHY=", why_escaped); + + env_file_fputs_assignment(f, "FIFO=", i->fifo_path); r = flink_tmpfile(f, temp_path, i->state_file, LINK_TMPFILE_REPLACE); if (r < 0) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 2ed8c428f57..c0038c1a629 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -302,20 +302,20 @@ int session_save(Session *s) { fprintf(f, "# This is private data. Do not parse.\n" "UID="UID_FMT"\n" - "USER=%s\n" "ACTIVE=%s\n" "IS_DISPLAY=%s\n" "STATE=%s\n" "REMOTE=%s\n" "LEADER_FD_SAVED=%s\n", s->user->user_record->uid, - s->user->user_record->user_name, one_zero(session_is_active(s)), one_zero(s->user->display == s), session_state_to_string(session_get_state(s)), one_zero(s->remote), one_zero(s->leader_fd_saved)); + env_file_fputs_assignment(f, "USER=", s->user->user_record->user_name); + if (s->type >= 0) fprintf(f, "TYPE=%s\n", session_type_to_string(s->type)); @@ -325,62 +325,20 @@ int session_save(Session *s) { if (s->class >= 0) fprintf(f, "CLASS=%s\n", session_class_to_string(s->class)); - if (s->scope) - fprintf(f, "SCOPE=%s\n", s->scope); - if (s->scope_job) - fprintf(f, "SCOPE_JOB=%s\n", s->scope_job); - + env_file_fputs_assignment(f, "SCOPE=", s->scope); + env_file_fputs_assignment(f, "SCOPE_JOB=", s->scope_job); if (s->seat) - fprintf(f, "SEAT=%s\n", s->seat->id); - - if (s->tty) - fprintf(f, "TTY=%s\n", s->tty); + env_file_fputs_assignment(f, "SEAT=", s->seat->id); + env_file_fputs_assignment(f, "TTY=", s->tty); if (s->tty_validity >= 0) fprintf(f, "TTY_VALIDITY=%s\n", tty_validity_to_string(s->tty_validity)); - if (s->display) - fprintf(f, "DISPLAY=%s\n", s->display); - - if (s->remote_host) { - _cleanup_free_ char *escaped = NULL; - - escaped = cescape(s->remote_host); - if (!escaped) - return log_oom(); - - fprintf(f, "REMOTE_HOST=%s\n", escaped); - } - - if (s->remote_user) { - _cleanup_free_ char *escaped = NULL; - - escaped = cescape(s->remote_user); - if (!escaped) - return log_oom(); - - fprintf(f, "REMOTE_USER=%s\n", escaped); - } - - if (s->service) { - _cleanup_free_ char *escaped = NULL; - - escaped = cescape(s->service); - if (!escaped) - return log_oom(); - - fprintf(f, "SERVICE=%s\n", escaped); - } - - if (s->desktop) { - _cleanup_free_ char *escaped = NULL; - - escaped = cescape(s->desktop); - if (!escaped) - return log_oom(); - - fprintf(f, "DESKTOP=%s\n", escaped); - } + env_file_fputs_assignment(f, "DISPLAY=", s->display); + env_file_fputs_assignment(f, "REMOTE_HOST=", s->remote_host); + env_file_fputs_assignment(f, "REMOTE_USER=", s->remote_user); + env_file_fputs_assignment(f, "SERVICE=", s->service); + env_file_fputs_assignment(f, "DESKTOP=", s->desktop); if (s->seat && seat_has_vts(s->seat)) fprintf(f, "VTNR=%u\n", s->vtnr); @@ -402,7 +360,7 @@ int session_save(Session *s) { s->timestamp.monotonic); if (s->controller) { - fprintf(f, "CONTROLLER=%s\n", s->controller); + env_file_fputs_assignment(f, "CONTROLLER=", s->controller); session_save_devices(s, f); } diff --git a/src/login/logind-user.c b/src/login/logind-user.c index c854b1e5fd5..a1f7c439f23 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -174,17 +174,11 @@ static int user_save_internal(User *u) { user_gc_mode_to_string(u->gc_mode)); /* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */ - if (u->runtime_path) - fprintf(f, "RUNTIME=%s\n", u->runtime_path); - - if (u->runtime_dir_job) - fprintf(f, "RUNTIME_DIR_JOB=%s\n", u->runtime_dir_job); - - if (u->service_manager_job) - fprintf(f, "SERVICE_JOB=%s\n", u->service_manager_job); - + env_file_fputs_assignment(f, "RUNTIME=", u->runtime_path); + env_file_fputs_assignment(f, "RUNTIME_DIR_JOB=", u->runtime_dir_job); + env_file_fputs_assignment(f, "SERVICE_JOB=", u->service_manager_job); if (u->display) - fprintf(f, "DISPLAY=%s\n", u->display->id); + env_file_fputs_assignment(f, "DISPLAY=%s\n", u->display->id); if (dual_timestamp_is_set(&u->timestamp)) fprintf(f,