Blame SOURCES/0071-basic-process-util-limit-command-line-lengths-to-_SC.patch

a3e2b5
From 6298317e2d0dffb1ff4ecebedb8709645de36b6a Mon Sep 17 00:00:00 2001
a3e2b5
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
a3e2b5
Date: Wed, 5 Dec 2018 18:48:23 +0100
a3e2b5
Subject: [PATCH] basic/process-util: limit command line lengths to _SC_ARG_MAX
a3e2b5
a3e2b5
This affects systemd-journald and systemd-coredump.
a3e2b5
a3e2b5
Example entry:
a3e2b5
$ journalctl -o export -n1 'MESSAGE=Something logged'
a3e2b5
__CURSOR=s=976542d120c649f494471be317829ef9;i=34e;b=4871e4c474574ce4a462dfe3f1c37f06;m=c7d0c37dd2;t=57c4ac58f3b98;x=67598e942bd23dc0
a3e2b5
__REALTIME_TIMESTAMP=1544035467475864
a3e2b5
__MONOTONIC_TIMESTAMP=858200964562
a3e2b5
_BOOT_ID=4871e4c474574ce4a462dfe3f1c37f06
a3e2b5
PRIORITY=6
a3e2b5
_UID=1000
a3e2b5
_GID=1000
a3e2b5
_CAP_EFFECTIVE=0
a3e2b5
_SELINUX_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
a3e2b5
_AUDIT_SESSION=1
a3e2b5
_AUDIT_LOGINUID=1000
a3e2b5
_SYSTEMD_OWNER_UID=1000
a3e2b5
_SYSTEMD_UNIT=user@1000.service
a3e2b5
_SYSTEMD_SLICE=user-1000.slice
a3e2b5
_SYSTEMD_USER_SLICE=-.slice
a3e2b5
_SYSTEMD_INVOCATION_ID=1c4a469986d448719cb0f9141a10810e
a3e2b5
_MACHINE_ID=08a5690a2eed47cf92ac0a5d2e3cf6b0
a3e2b5
_HOSTNAME=krowka
a3e2b5
_TRANSPORT=syslog
a3e2b5
SYSLOG_FACILITY=17
a3e2b5
SYSLOG_IDENTIFIER=syslog-caller
a3e2b5
MESSAGE=Something logged
a3e2b5
_COMM=poc
a3e2b5
_EXE=/home/zbyszek/src/systemd-work3/poc
a3e2b5
_SYSTEMD_CGROUP=/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
a3e2b5
_SYSTEMD_USER_UNIT=gnome-terminal-server.service
a3e2b5
SYSLOG_PID=4108
a3e2b5
SYSLOG_TIMESTAMP=Dec  5 19:44:27
a3e2b5
_PID=4108
a3e2b5
_CMDLINE=./poc AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
a3e2b5
_SOURCE_REALTIME_TIMESTAMP=1544035467475848
a3e2b5
a3e2b5
$ journalctl -o export -n1 'MESSAGE=Something logged' --output-fields=_CMDLINE|wc
a3e2b5
      6    2053 2097410
a3e2b5
a3e2b5
2MB might be hard for some clients to use meaningfully, but OTOH, it is
a3e2b5
important to log the full commandline sometimes. For example, when the program
a3e2b5
is crashing, the exact argument list is useful.
a3e2b5
a3e2b5
(cherry-picked from commit 2d5d2e0cc5171c6795d2a485841474345d9e30ab)
a3e2b5
a3e2b5
Related: #1664976
a3e2b5
---
a3e2b5
 src/basic/process-util.c | 73 ++++++++++++++--------------------------
a3e2b5
 1 file changed, 25 insertions(+), 48 deletions(-)
a3e2b5
a3e2b5
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
a3e2b5
index 0a4f917cbd..a20f1e3ccf 100644
a3e2b5
--- a/src/basic/process-util.c
a3e2b5
+++ b/src/basic/process-util.c
a3e2b5
@@ -128,6 +128,13 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
a3e2b5
 
a3e2b5
         (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
a3e2b5
 
a3e2b5
+        if (max_length == 0) {
a3e2b5
+                /* This is supposed to be a safety guard against runaway command lines. */
a3e2b5
+                long l = sysconf(_SC_ARG_MAX);
a3e2b5
+                assert(l > 0);
a3e2b5
+                max_length = l;
a3e2b5
+        }
a3e2b5
+
a3e2b5
         if (max_length == 1) {
a3e2b5
 
a3e2b5
                 /* If there's only room for one byte, return the empty string */
a3e2b5
@@ -138,32 +145,6 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
a3e2b5
                 *line = ans;
a3e2b5
                 return 0;
a3e2b5
 
a3e2b5
-        } else if (max_length == 0) {
a3e2b5
-                size_t len = 0, allocated = 0;
a3e2b5
-
a3e2b5
-                while ((c = getc(f)) != EOF) {
a3e2b5
-
a3e2b5
-                        if (!GREEDY_REALLOC(ans, allocated, len+3)) {
a3e2b5
-                                free(ans);
a3e2b5
-                                return -ENOMEM;
a3e2b5
-                        }
a3e2b5
-
a3e2b5
-                        if (isprint(c)) {
a3e2b5
-                                if (space) {
a3e2b5
-                                        ans[len++] = ' ';
a3e2b5
-                                        space = false;
a3e2b5
-                                }
a3e2b5
-
a3e2b5
-                                ans[len++] = c;
a3e2b5
-                        } else if (len > 0)
a3e2b5
-                                space = true;
a3e2b5
-               }
a3e2b5
-
a3e2b5
-                if (len > 0)
a3e2b5
-                        ans[len] = '\0';
a3e2b5
-                else
a3e2b5
-                        ans = mfree(ans);
a3e2b5
-
a3e2b5
         } else {
a3e2b5
                 bool dotdotdot = false;
a3e2b5
                 size_t left;
a3e2b5
@@ -235,34 +216,30 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
a3e2b5
                 if (h < 0)
a3e2b5
                         return h;
a3e2b5
 
a3e2b5
-                if (max_length == 0)
a3e2b5
-                        ans = strjoin("[", t, "]");
a3e2b5
-                else {
a3e2b5
-                        size_t l;
a3e2b5
-
a3e2b5
-                        l = strlen(t);
a3e2b5
+                size_t l = strlen(t);
a3e2b5
 
a3e2b5
-                        if (l + 3 <= max_length)
a3e2b5
-                                ans = strjoin("[", t, "]");
a3e2b5
-                        else if (max_length <= 6) {
a3e2b5
+                if (l + 3 <= max_length) {
a3e2b5
+                        ans = strjoin("[", t, "]");
a3e2b5
+                        if (!ans)
a3e2b5
+                                return -ENOMEM;
a3e2b5
 
a3e2b5
-                                ans = new(char, max_length);
a3e2b5
-                                if (!ans)
a3e2b5
-                                        return -ENOMEM;
a3e2b5
+                } else if (max_length <= 6) {
a3e2b5
+                        ans = new(char, max_length);
a3e2b5
+                        if (!ans)
a3e2b5
+                                return -ENOMEM;
a3e2b5
 
a3e2b5
-                                memcpy(ans, "[...]", max_length-1);
a3e2b5
-                                ans[max_length-1] = 0;
a3e2b5
-                        } else {
a3e2b5
-                                t[max_length - 6] = 0;
a3e2b5
+                        memcpy(ans, "[...]", max_length-1);
a3e2b5
+                        ans[max_length-1] = 0;
a3e2b5
+                } else {
a3e2b5
+                        t[max_length - 6] = 0;
a3e2b5
 
a3e2b5
-                                /* Chop off final spaces */
a3e2b5
-                                delete_trailing_chars(t, WHITESPACE);
a3e2b5
+                        /* Chop off final spaces */
a3e2b5
+                        delete_trailing_chars(t, WHITESPACE);
a3e2b5
 
a3e2b5
-                                ans = strjoin("[", t, "...]");
a3e2b5
-                        }
a3e2b5
+                        ans = strjoin("[", t, "...]");
a3e2b5
+                        if (!ans)
a3e2b5
+                                return -ENOMEM;
a3e2b5
                 }
a3e2b5
-                if (!ans)
a3e2b5
-                        return -ENOMEM;
a3e2b5
         }
a3e2b5
 
a3e2b5
         *line = ans;