From 03bf37877f1c7045724cba12d69e93c8c411646e Mon Sep 17 00:00:00 2001 From: Anita Zhang Date: Wed, 26 Jan 2022 10:53:40 -0800 Subject: [PATCH] tree-wide: don't use strjoina() on getenv() values Avoid doing stack allocations on environment variables. (cherry picked from commit 1d3b68f6e1538b6a86cbe3650d8b81df2877ef42) Related: #2017035 --- src/basic/path-lookup.c | 8 ++++++-- src/core/dbus.c | 8 ++++++-- src/home/homed-home.c | 10 +++++++--- src/home/homed-manager.c | 26 ++++++++++++++++++-------- src/run/run.c | 7 +++++-- src/shared/pager.c | 9 +++++++-- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/basic/path-lookup.c b/src/basic/path-lookup.c index 6fb8c40e7a..921a30cef7 100644 --- a/src/basic/path-lookup.c +++ b/src/basic/path-lookup.c @@ -238,7 +238,7 @@ static int acquire_generator_dirs( char **generator_early, char **generator_late) { - _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL; + _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *p = NULL; const char *prefix; assert(generator); @@ -261,7 +261,11 @@ static int acquire_generator_dirs( if (!e) return -ENXIO; - prefix = strjoina(e, "/systemd"); + p = path_join(e, "/systemd"); + if (!p) + return -ENOMEM; + + prefix = p; } x = path_join(prefix, "generator"); diff --git a/src/core/dbus.c b/src/core/dbus.c index 2c5bda58f9..073675ceef 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -925,14 +925,18 @@ int bus_init_private(Manager *m) { r = sockaddr_un_set_path(&sa.un, "/run/systemd/private"); } else { - const char *e, *joined; + _cleanup_free_ char *joined = NULL; + const char *e; e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), "XDG_RUNTIME_DIR is not set, refusing."); - joined = strjoina(e, "/systemd/private"); + joined = path_join(e, "/systemd/private"); + if (!joined) + return log_oom(); + r = sockaddr_un_set_path(&sa.un, joined); } if (r < 0) diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 470c7f07f6..1340cf30d3 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -1185,14 +1185,18 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord if (r < 0) return r; if (r == 0) { + _cleanup_free_ char *joined = NULL; const char *homework, *suffix, *unix_path; /* Child */ suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - unix_path = strjoina("/run/systemd/home/notify.", suffix); - else + if (suffix) { + joined = strjoin("/run/systemd/home/notify.", suffix); + if (!joined) + return log_oom(); + unix_path = joined; + } else unix_path = "/run/systemd/home/notify"; if (setenv("NOTIFY_SOCKET", unix_path, 1) < 0) { diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index 6c178b8a0e..c1ec555cac 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -936,6 +936,7 @@ int manager_enumerate_images(Manager *m) { } static int manager_connect_bus(Manager *m) { + _cleanup_free_ char *b = NULL; const char *suffix, *busname; int r; @@ -955,9 +956,12 @@ static int manager_connect_bus(Manager *m) { return r; suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - busname = strjoina("org.freedesktop.home1.", suffix); - else + if (suffix) { + b = strjoin("org.freedesktop.home1.", suffix); + if (!b) + return log_oom(); + busname = b; + } else busname = "org.freedesktop.home1"; r = sd_bus_request_name_async(m->bus, NULL, busname, 0, NULL, NULL); @@ -974,6 +978,7 @@ static int manager_connect_bus(Manager *m) { } static int manager_bind_varlink(Manager *m) { + _cleanup_free_ char *p = NULL; const char *suffix, *socket_path; int r; @@ -999,9 +1004,12 @@ static int manager_bind_varlink(Manager *m) { /* To make things easier to debug, when working from a homed managed home directory, let's optionally * use a different varlink socket name */ suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - socket_path = strjoina("/run/systemd/userdb/io.systemd.Home.", suffix); - else + if (suffix) { + p = strjoin("/run/systemd/userdb/io.systemd.Home.", suffix); + if (!p) + return log_oom(); + socket_path = p; + } else socket_path = "/run/systemd/userdb/io.systemd.Home"; r = varlink_server_listen_address(m->varlink_server, socket_path, 0666); @@ -1159,9 +1167,11 @@ static int manager_listen_notify(Manager *m) { suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); if (suffix) { - const char *unix_path; + _cleanup_free_ char *unix_path = NULL; - unix_path = strjoina("/run/systemd/home/notify.", suffix); + unix_path = strjoin("/run/systemd/home/notify.", suffix); + if (!unix_path) + return log_oom(); r = sockaddr_un_set_path(&sa.un, unix_path); if (r < 0) return log_error_errno(r, "Socket path %s does not fit in sockaddr_un: %m", unix_path); diff --git a/src/run/run.c b/src/run/run.c index ff24373847..e75b027542 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -794,9 +794,12 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p e = getenv("TERM"); if (e) { - char *n; + _cleanup_free_ char *n = NULL; + + n = strjoin("TERM=", e); + if (!n) + return log_oom(); - n = strjoina("TERM=", e); r = sd_bus_message_append(m, "(sv)", "Environment", "as", 1, n); diff --git a/src/shared/pager.c b/src/shared/pager.c index f75ef62d2d..9426d3ef98 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -86,6 +86,7 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) { void pager_open(PagerFlags flags) { _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 }; _cleanup_strv_free_ char **pager_args = NULL; + _cleanup_free_ char *l = NULL; const char *pager, *less_opts; int r; @@ -131,8 +132,12 @@ void pager_open(PagerFlags flags) { less_opts = getenv("SYSTEMD_LESS"); if (!less_opts) less_opts = "FRSXMK"; - if (flags & PAGER_JUMP_TO_END) - less_opts = strjoina(less_opts, " +G"); + if (flags & PAGER_JUMP_TO_END) { + l = strjoin(less_opts, " +G"); + if (!l) + return (void) log_oom(); + less_opts = l; + } /* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */ r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);