dryang / rpms / systemd

Forked from rpms/systemd a year ago
Clone
Pablo Greco 48fc63
From 78c1a16731f8bec0e854ed570292afc8bf3d8030 Mon Sep 17 00:00:00 2001
Pablo Greco 48fc63
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Pablo Greco 48fc63
Date: Thu, 3 Jan 2019 11:35:22 +0100
Pablo Greco 48fc63
Subject: [PATCH] journald: do not store the iovec entry for process
Pablo Greco 48fc63
 commandline on stack
Pablo Greco 48fc63
Pablo Greco 48fc63
This fixes a crash where we would read the commandline, whose length is under
Pablo Greco 48fc63
control of the sending program, and then crash when trying to create a stack
Pablo Greco 48fc63
allocation for it.
Pablo Greco 48fc63
Pablo Greco 48fc63
CVE-2018-16864
Pablo Greco 48fc63
https://bugzilla.redhat.com/show_bug.cgi?id=1653855
Pablo Greco 48fc63
Pablo Greco 48fc63
The message actually doesn't get written to disk, because
Pablo Greco 48fc63
journal_file_append_entry() returns -E2BIG.
Pablo Greco 48fc63
Pablo Greco 48fc63
Resolves: #1657788
Pablo Greco 48fc63
---
Pablo Greco 48fc63
 src/journal/coredump.c        | 189 +++++++++++++---------------------
Pablo Greco 48fc63
 src/journal/journald-server.c |  13 +--
Pablo Greco 48fc63
 src/shared/util.c             |  17 +++
Pablo Greco 48fc63
 src/shared/util.h             |   7 ++
Pablo Greco 48fc63
 4 files changed, 98 insertions(+), 128 deletions(-)
Pablo Greco 48fc63
Pablo Greco 48fc63
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
Pablo Greco 48fc63
index 59ccd46bb0..40de86f050 100644
Pablo Greco 48fc63
--- a/src/journal/coredump.c
Pablo Greco 48fc63
+++ b/src/journal/coredump.c
Pablo Greco 48fc63
@@ -526,14 +526,6 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
Pablo Greco 48fc63
 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
 int main(int argc, char* argv[]) {
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        /* The small core field we allocate on the stack, to keep things simple */
Pablo Greco 48fc63
-        char
Pablo Greco 48fc63
-                *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
Pablo Greco 48fc63
-                *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL,
Pablo Greco 48fc63
-                *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL,
Pablo Greco 48fc63
-                *core_slice = NULL;
Pablo Greco 48fc63
-
Pablo Greco 48fc63
         /* The larger ones we allocate on the heap */
Pablo Greco 48fc63
         _cleanup_free_ char
Pablo Greco 48fc63
                 *core_timestamp = NULL,  *core_message = NULL, *coredump_data = NULL, *core_owner_uid = NULL,
Pablo Greco 48fc63
@@ -547,7 +539,8 @@ int main(int argc, char* argv[]) {
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         struct iovec iovec[26];
Pablo Greco 48fc63
         off_t coredump_size;
Pablo Greco 48fc63
-        int r, j = 0;
Pablo Greco 48fc63
+        int r;
Pablo Greco 48fc63
+        unsigned int n_iovec = 0;
Pablo Greco 48fc63
         uid_t uid, owner_uid;
Pablo Greco 48fc63
         gid_t gid;
Pablo Greco 48fc63
         pid_t pid;
Pablo Greco 48fc63
@@ -634,151 +627,107 @@ int main(int argc, char* argv[]) {
Pablo Greco 48fc63
                         goto finish;
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                core_unit = strjoina("COREDUMP_UNIT=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        } else if (cg_pid_get_user_unit(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_unit = strjoina("COREDUMP_USER_UNIT=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+                if (!set_iovec_field_free(iovec, &n_iovec, "COREDUMP_UNIT=", t)) {
Pablo Greco 48fc63
+                        r = log_oom();
Pablo Greco 48fc63
+                        goto finish;
Pablo Greco 48fc63
+                }
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (core_unit)
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_unit);
Pablo Greco 48fc63
+        if (cg_pid_get_user_unit(pid, &t) >= 0) {
Pablo Greco 48fc63
+                if (!set_iovec_field_free(iovec, &n_iovec, "COREDUMP_USER_UNIT=", t)) {
Pablo Greco 48fc63
+                        r = log_oom();
Pablo Greco 48fc63
+                        goto finish;
Pablo Greco 48fc63
+                }
Pablo Greco 48fc63
+        }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         /* OK, now we know it's not the journal, hence we can make use
Pablo Greco 48fc63
          * of it now. */
Pablo Greco 48fc63
         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
Pablo Greco 48fc63
         log_open();
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        core_pid = strjoina("COREDUMP_PID=", info[INFO_PID]);
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], core_pid);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        core_uid = strjoina("COREDUMP_UID=", info[INFO_UID]);
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], core_uid);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        core_gid = strjoina("COREDUMP_GID=", info[INFO_GID]);
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], core_gid);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        core_signal = strjoina("COREDUMP_SIGNAL=", info[INFO_SIGNAL]);
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], core_signal);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        if (sd_pid_get_session(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_session = strjoina("COREDUMP_SESSION=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_session);
Pablo Greco 48fc63
+        if (!set_iovec_string_field(iovec, &n_iovec, "COREDUMP_PID=", info[INFO_PID])) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
Pablo Greco 48fc63
-                r = asprintf(&core_owner_uid,
Pablo Greco 48fc63
-                             "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
Pablo Greco 48fc63
-                if (r > 0)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_owner_uid);
Pablo Greco 48fc63
+        if (!set_iovec_string_field(iovec, &n_iovec, "COREDUMP_UID=", info[INFO_UID])) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (sd_pid_get_slice(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_slice = strjoina("COREDUMP_SLICE=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (!set_iovec_string_field(iovec, &n_iovec, "COREDUMP_GID=", info[INFO_GID])) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
+        }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_slice);
Pablo Greco 48fc63
+        if (!set_iovec_string_field(iovec, &n_iovec, "COREDUMP_SIGNAL=", info[INFO_SIGNAL])) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (comm) {
Pablo Greco 48fc63
-                core_comm = strjoina("COREDUMP_COMM=", comm);
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_comm);
Pablo Greco 48fc63
+        if (comm && !set_iovec_string_field(iovec, &n_iovec, "COREDUMP_COMM=", comm)) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (exe) {
Pablo Greco 48fc63
-                core_exe = strjoina("COREDUMP_EXE=", exe);
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_exe);
Pablo Greco 48fc63
+        if (exe && !set_iovec_string_field(iovec, &n_iovec, "COREDUMP_EXE=", exe)) {
Pablo Greco 48fc63
+                r = log_oom();
Pablo Greco 48fc63
+                goto finish;
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (get_process_cmdline(pid, 0, false, &t) >= 0) {
Pablo Greco 48fc63
-                core_cmdline = strjoina("COREDUMP_CMDLINE=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (sd_pid_get_session(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_SESSION=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_cmdline);
Pablo Greco 48fc63
+        if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
Pablo Greco 48fc63
+                r = asprintf(&core_owner_uid,
Pablo Greco 48fc63
+                             "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
Pablo Greco 48fc63
+                if (r > 0)
Pablo Greco 48fc63
+                        IOVEC_SET_STRING(iovec[n_iovec++], core_owner_uid);
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) {
Pablo Greco 48fc63
-                core_cgroup = strjoina("COREDUMP_CGROUP=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (sd_pid_get_slice(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_SLICE=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_cgroup);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (get_process_cmdline(pid, 0, false, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_CMDLINE=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (compose_open_fds(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_open_fds = strappend("COREDUMP_OPEN_FDS=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_CGROUP=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                if (core_open_fds)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_open_fds);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (compose_open_fds(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_OPEN_FDS=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         p = procfs_file_alloca(pid, "status");
Pablo Greco 48fc63
-        if (read_full_file(p, &t, NULL) >= 0) {
Pablo Greco 48fc63
-                core_proc_status = strappend("COREDUMP_PROC_STATUS=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                if (core_proc_status)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_proc_status);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (read_full_file(p, &t, NULL) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_PROC_STATUS=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         p = procfs_file_alloca(pid, "maps");
Pablo Greco 48fc63
-        if (read_full_file(p, &t, NULL) >= 0) {
Pablo Greco 48fc63
-                core_proc_maps = strappend("COREDUMP_PROC_MAPS=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                if (core_proc_maps)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_proc_maps);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (read_full_file(p, &t, NULL) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_PROC_MAPS=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         p = procfs_file_alloca(pid, "limits");
Pablo Greco 48fc63
-        if (read_full_file(p, &t, NULL) >= 0) {
Pablo Greco 48fc63
-                core_proc_limits = strappend("COREDUMP_PROC_LIMITS=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                if (core_proc_limits)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_proc_limits);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (read_full_file(p, &t, NULL) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_PROC_LIMITS=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         p = procfs_file_alloca(pid, "cgroup");
Pablo Greco 48fc63
-        if (read_full_file(p, &t, NULL) >=0) {
Pablo Greco 48fc63
-                core_proc_cgroup = strappend("COREDUMP_PROC_CGROUP=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (read_full_file(p, &t, NULL) >=0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_PROC_CGROUP=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                if (core_proc_cgroup)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_proc_cgroup);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        if (get_process_cwd(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_cwd = strjoina("COREDUMP_CWD=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
+        if (get_process_cwd(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_CWD=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_cwd);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (get_process_root(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_ROOT=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        if (get_process_root(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_root = strjoina("COREDUMP_ROOT=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_root);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-        if (get_process_environ(pid, &t) >= 0) {
Pablo Greco 48fc63
-                core_environ = strappend("COREDUMP_ENVIRON=", t);
Pablo Greco 48fc63
-                free(t);
Pablo Greco 48fc63
-
Pablo Greco 48fc63
-                if (core_environ)
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[j++], core_environ);
Pablo Greco 48fc63
-        }
Pablo Greco 48fc63
+        if (get_process_environ(pid, &t) >= 0)
Pablo Greco 48fc63
+                set_iovec_field_free(iovec, &n_iovec, "COREDUMP_ENVIRON=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL);
Pablo Greco 48fc63
         if (core_timestamp)
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_timestamp);
Pablo Greco 48fc63
+                IOVEC_SET_STRING(iovec[n_iovec++], core_timestamp);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
Pablo Greco 48fc63
-        IOVEC_SET_STRING(iovec[j++], "PRIORITY=2");
Pablo Greco 48fc63
+        IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
Pablo Greco 48fc63
+        IOVEC_SET_STRING(iovec[n_iovec++], "PRIORITY=2");
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         /* Vacuum before we write anything again */
Pablo Greco 48fc63
         coredump_vacuum(-1, arg_keep_free, arg_max_use);
Pablo Greco 48fc63
@@ -800,7 +749,7 @@ int main(int argc, char* argv[]) {
Pablo Greco 48fc63
                 const char *coredump_filename;
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 coredump_filename = strjoina("COREDUMP_FILENAME=", filename);
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], coredump_filename);
Pablo Greco 48fc63
+                IOVEC_SET_STRING(iovec[n_iovec++], coredump_filename);
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         /* Vacuum again, but exclude the coredump we just created */
Pablo Greco 48fc63
@@ -838,7 +787,7 @@ int main(int argc, char* argv[]) {
Pablo Greco 48fc63
 log:
Pablo Greco 48fc63
         core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.", NULL);
Pablo Greco 48fc63
         if (core_message)
Pablo Greco 48fc63
-                IOVEC_SET_STRING(iovec[j++], core_message);
Pablo Greco 48fc63
+                IOVEC_SET_STRING(iovec[n_iovec++], core_message);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
         /* Optionally store the entire coredump in the journal */
Pablo Greco 48fc63
         if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
Pablo Greco 48fc63
@@ -849,13 +798,13 @@ log:
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
Pablo Greco 48fc63
                 if (r >= 0) {
Pablo Greco 48fc63
-                        iovec[j].iov_base = coredump_data;
Pablo Greco 48fc63
-                        iovec[j].iov_len = sz;
Pablo Greco 48fc63
-                        j++;
Pablo Greco 48fc63
+                        iovec[n_iovec].iov_base = coredump_data;
Pablo Greco 48fc63
+                        iovec[n_iovec].iov_len = sz;
Pablo Greco 48fc63
+                        n_iovec++;
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
-        r = sd_journal_sendv(iovec, j);
Pablo Greco 48fc63
+        r = sd_journal_sendv(iovec, n_iovec);
Pablo Greco 48fc63
         if (r < 0)
Pablo Greco 48fc63
                 log_error_errno(r, "Failed to log coredump: %m");
Pablo Greco 48fc63
 
Pablo Greco 48fc63
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
Pablo Greco 48fc63
index 7e67e055e3..c35858247b 100644
Pablo Greco 48fc63
--- a/src/journal/journald-server.c
Pablo Greco 48fc63
+++ b/src/journal/journald-server.c
Pablo Greco 48fc63
@@ -788,9 +788,9 @@ static void dispatch_message_real(
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 r = get_process_cmdline(ucred->pid, 0, false, &t);
Pablo Greco 48fc63
                 if (r >= 0) {
Pablo Greco 48fc63
-                        x = strjoina("_CMDLINE=", t);
Pablo Greco 48fc63
-                        free(t);
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[n++], x);
Pablo Greco 48fc63
+                        /* At most _SC_ARG_MAX (2MB usually), which is too much to put on stack.
Pablo Greco 48fc63
+                         * Let's use a heap allocation for this one. */
Pablo Greco 48fc63
+                        set_iovec_field_free(iovec, &n, "_CMDLINE=", t);
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 r = get_process_capeff(ucred->pid, &t);
Pablo Greco 48fc63
@@ -915,11 +915,8 @@ static void dispatch_message_real(
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 r = get_process_cmdline(object_pid, 0, false, &t);
Pablo Greco 48fc63
-                if (r >= 0) {
Pablo Greco 48fc63
-                        x = strjoina("OBJECT_CMDLINE=", t);
Pablo Greco 48fc63
-                        free(t);
Pablo Greco 48fc63
-                        IOVEC_SET_STRING(iovec[n++], x);
Pablo Greco 48fc63
-                }
Pablo Greco 48fc63
+                if (r >= 0)
Pablo Greco 48fc63
+                        set_iovec_field_free(iovec, &n, "OBJECT_CMDLINE=", t);
Pablo Greco 48fc63
 
Pablo Greco 48fc63
 #ifdef HAVE_AUDIT
Pablo Greco 48fc63
                 r = audit_session_from_pid(object_pid, &audit);
Pablo Greco 48fc63
diff --git a/src/shared/util.c b/src/shared/util.c
Pablo Greco 48fc63
index 78967103a6..c71e021cd7 100644
Pablo Greco 48fc63
--- a/src/shared/util.c
Pablo Greco 48fc63
+++ b/src/shared/util.c
Pablo Greco 48fc63
@@ -2275,6 +2275,23 @@ int flush_fd(int fd) {
Pablo Greco 48fc63
         }
Pablo Greco 48fc63
 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+char* set_iovec_string_field(struct iovec *iovec, unsigned int *n_iovec, const char *field, const char *value) {
Pablo Greco 48fc63
+        char *x;
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+        x = strappend(field, value);
Pablo Greco 48fc63
+        if (x)
Pablo Greco 48fc63
+                iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x);
Pablo Greco 48fc63
+        return x;
Pablo Greco 48fc63
+}
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+char* set_iovec_field_free(struct iovec *iovec, unsigned int *n_iovec, const char *field, char *value) {
Pablo Greco 48fc63
+        char *x;
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+        x = set_iovec_string_field(iovec, n_iovec, field, value);
Pablo Greco 48fc63
+        free(value);
Pablo Greco 48fc63
+        return x;
Pablo Greco 48fc63
+}
Pablo Greco 48fc63
+
Pablo Greco 48fc63
 int acquire_terminal(
Pablo Greco 48fc63
                 const char *name,
Pablo Greco 48fc63
                 bool fail,
Pablo Greco 48fc63
diff --git a/src/shared/util.h b/src/shared/util.h
Pablo Greco 48fc63
index cf096aa07b..8fc237495a 100644
Pablo Greco 48fc63
--- a/src/shared/util.h
Pablo Greco 48fc63
+++ b/src/shared/util.h
Pablo Greco 48fc63
@@ -1140,3 +1140,10 @@ static inline void block_signals_reset(sigset_t *ss) {
Pablo Greco 48fc63
                 _t;                                                                \
Pablo Greco 48fc63
         })
Pablo Greco 48fc63
 
Pablo Greco 48fc63
+#define IOVEC_INIT(base, len) { .iov_base = (base), .iov_len = (len) }
Pablo Greco 48fc63
+#define IOVEC_MAKE(base, len) (struct iovec) IOVEC_INIT(base, len)
Pablo Greco 48fc63
+#define IOVEC_INIT_STRING(string) IOVEC_INIT((char*) string, strlen(string))
Pablo Greco 48fc63
+#define IOVEC_MAKE_STRING(string) (struct iovec) IOVEC_INIT_STRING(string)
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+char* set_iovec_string_field(struct iovec *iovec, unsigned int *n_iovec, const char *field, const char *value);
Pablo Greco 48fc63
+char* set_iovec_field_free(struct iovec *iovec, unsigned int *n_iovec, const char *field, char *value);