From d8ddfcf4e0f7342f362d587a2789d69773a20f1c Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Tue, 21 May 2019 14:56:47 +0000
Subject: [PATCH] daemon: avoid infinite crash loops
Export an environment variable as a mark for abrtd (abrt-server) to
identify processes directly involved in ABRT post-mortem processing.
We must not run post-mortem EVENTs on problem directories caused by ABRT
itself because we could create an infinite loop.
There are to ways how to handle such directories:
* in non-debug mode: log a short message and remove them without
other actions - we must not leave them in the dump location by
default because the dump location would be growing
* in debug mode: log a more verbose message and leave them as they
are - we don need to have worries about the dump location growing
because someone intentionally enable the debug mode
Related: rhbz#1246539
cherry-picked from https://github.com/abrt/abrt/commit/68e0efaa36f6d4aabfd8ecf71bf0c22adfc72b03
Related: rhbz#1688368
Signed-off-by: Martin Kutlak <mkutlak@redhat.com>
---
src/daemon/abrt-server.c | 54 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/src/daemon/abrt-server.c b/src/daemon/abrt-server.c
index e1dfc4af..60eb9b66 100644
--- a/src/daemon/abrt-server.c
+++ b/src/daemon/abrt-server.c
@@ -28,6 +28,7 @@
/* We exit after this many seconds */
#define TIMEOUT 10
+#define ABRT_SERVER_EVENT_ENV "ABRT_SERVER_PID"
/*
Unix socket in ABRT daemon for creating new dump directories.
@@ -206,10 +207,11 @@ static pid_t spawn_event_handler_child(const char *dump_dir_name, const char *ev
int flags = EXECFLG_INPUT_NUL | EXECFLG_OUTPUT | EXECFLG_QUIET | EXECFLG_ERR2OUT;
VERB1 flags &= ~EXECFLG_QUIET;
- char *env_vec[2];
+ char *env_vec[3];
/* Intercept ASK_* messages in Client API -> don't wait for user response */
env_vec[0] = xstrdup("REPORT_CLIENT_NONINTERACTIVE=1");
- env_vec[1] = NULL;
+ env_vec[1] = xasprintf("%s=%d", ABRT_SERVER_EVENT_ENV, getpid());
+ env_vec[2] = NULL;
pid_t child = fork_execv_on_steroids(flags, args, pipeout,
env_vec, /*dir:*/ NULL,
@@ -219,6 +221,23 @@ static pid_t spawn_event_handler_child(const char *dump_dir_name, const char *ev
return child;
}
+static int problem_dump_dir_was_provoked_by_abrt_event(struct dump_dir *dd, char **provoker)
+{
+ char *env_var = NULL;
+ const int r = dd_get_env_variable(dd, ABRT_SERVER_EVENT_ENV, &env_var);
+
+ /* Dump directory doesn't contain the environ file */
+ if (r == -ENOENT)
+ return 0;
+
+ if (provoker != NULL)
+ *provoker = env_var;
+ else
+ free(env_var);
+
+ return env_var != NULL;
+}
+
static gboolean emit_new_problem_signal(gpointer data)
{
struct waiting_context *context = (struct waiting_context *)data;
@@ -254,6 +273,37 @@ static int run_post_create(const char *dirname)
if (g_settings_privatereports)
{
struct dump_dir *dd = dd_opendir(dirname, DD_OPEN_READONLY);
+
+ char *provoker = NULL;
+ const bool event_dir = dd && problem_dump_dir_was_provoked_by_abrt_event(dd, &provoker);
+ if (event_dir)
+ {
+ if (g_settings_debug_level == 0)
+ {
+ error_msg("Removing problem provoked by ABRT(pid:%s): '%s'", provoker, dirname);
+ dd_delete(dd);
+ }
+ else
+ {
+ char *dumpdir = NULL;
+ char *event = NULL;
+ char *reason = NULL;
+ char *cmdline = NULL;
+
+ /* Ignore errors */
+ dd_get_env_variable(dd, "DUMP_DIR", &dumpdir);
+ dd_get_env_variable(dd, "EVENT", &event);
+ reason = dd_load_text(dd, FILENAME_REASON);
+ cmdline = dd_load_text(dd, FILENAME_CMDLINE);
+
+ error_msg("ABRT_SERVER_PID=%s;DUMP_DIR='%s';EVENT='%s';REASON='%s';CMDLINE='%s'",
+ provoker, dumpdir, event, reason, cmdline);
+ }
+
+ free(provoker);
+ return 400;
+ }
+
const bool complete = dd && problem_dump_dir_is_complete(dd);
dd_close(dd);
if (complete)
--
2.21.0