You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
5.8 KiB
160 lines
5.8 KiB
From 6298317e2d0dffb1ff4ecebedb8709645de36b6a 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.
|
|
|
|
(cherry-picked from commit 2d5d2e0cc5171c6795d2a485841474345d9e30ab)
|
|
|
|
Related: #1664976
|
|
---
|
|
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 0a4f917cbd..a20f1e3ccf 100644
|
|
--- a/src/basic/process-util.c
|
|
+++ b/src/basic/process-util.c
|
|
@@ -128,6 +128,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 */
|
|
@@ -138,32 +145,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;
|
|
@@ -235,34 +216,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;
|
|
-
|
|
- l = strlen(t);
|
|
+ size_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;
|