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

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