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