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

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