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