package/systemd: fix memory leak in systemd-journald
Fixes #11911 Systemd-journald would leak memory when recording process info. Add patch files from upstream systemd. Note that the patch from 2d5d2e0cc5 was taken as well in order to make the needed commit apply cleanly. Bug report: https://github.com/systemd/systemd/issues/11502 Accepted patch: https://github.com/systemd/systemd/pull/11527 Signed-off-by: Jonah Petri <jonah@petri.us> [Peter: add bz reference, add s-o-b to patches, drop numbering] Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
This commit is contained in:
parent
9f52b9c292
commit
ae43e724e8
@ -0,0 +1,159 @@
|
||||
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 1/2] 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.
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,70 @@
|
||||
From eb1ec489eef8a32918bbfc56a268c9d10464584d Mon Sep 17 00:00:00 2001
|
||||
From: Michal Sekletar <msekleta@redhat.com>
|
||||
Date: Tue, 22 Jan 2019 14:29:50 +0100
|
||||
Subject: [PATCH 2/2] process-util: don't use overly large buffer to store
|
||||
process command line
|
||||
|
||||
Allocate new string as a return value and free our "scratch pad"
|
||||
buffer that is potentially much larger than needed (up to
|
||||
_SC_ARG_MAX).
|
||||
|
||||
Fixes #11502
|
||||
---
|
||||
src/basic/process-util.c | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||
index 31fdbd9346..78ce43b944 100644
|
||||
--- a/src/basic/process-util.c
|
||||
+++ b/src/basic/process-util.c
|
||||
@@ -102,7 +102,8 @@ int get_process_comm(pid_t pid, char **ret) {
|
||||
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
bool space = false;
|
||||
- char *k, *ans = NULL;
|
||||
+ char *k;
|
||||
+ _cleanup_free_ char *ans = NULL;
|
||||
const char *p;
|
||||
int c;
|
||||
|
||||
@@ -143,7 +144,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
|
||||
if (!ans)
|
||||
return -ENOMEM;
|
||||
|
||||
- *line = ans;
|
||||
+ *line = TAKE_PTR(ans);
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
@@ -208,7 +209,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
|
||||
_cleanup_free_ char *t = NULL;
|
||||
int h;
|
||||
|
||||
- free(ans);
|
||||
+ ans = mfree(ans);
|
||||
|
||||
if (!comm_fallback)
|
||||
return -ENOENT;
|
||||
@@ -241,9 +242,18 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
|
||||
if (!ans)
|
||||
return -ENOMEM;
|
||||
}
|
||||
+
|
||||
+ *line = TAKE_PTR(ans);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- *line = ans;
|
||||
+ k = realloc(ans, strlen(ans) + 1);
|
||||
+ if (!k)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ans = NULL;
|
||||
+ *line = k;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
Loading…
Reference in New Issue
Block a user