Blame SOURCES/0324-daemon-avoid-infinite-crash-loops.patch

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