Blame SOURCES/0232-ccpp-unify-log-message-of-ignored-crashes.patch

06486d
From 6724ba03fea310439c02f97d9429b921d12275c5 Mon Sep 17 00:00:00 2001
06486d
From: Matej Habrnal <mhabrnal@redhat.com>
06486d
Date: Thu, 19 May 2016 12:10:42 +0200
06486d
Subject: [PATCH] ccpp: unify log message of ignored crashes
06486d
06486d
ABRT will ignore crashes in executables for which absolute path matches one of
06486d
specified patterns.
06486d
06486d
Example of log messages in case of ignoring crashes:
06486d
- Crash's path is listed in 'IgnoredPath' in CCpp.conf
06486d
    Process 16431 (will_segfault) of user 0 killed by SIGSEGV - ignoring
06486d
    (listed in 'IgnoredPaths')
06486d
06486d
- Repeating crash
06486d
    Process 16219 (will_segfault) of user 1000 killed by SIGSEGV -
06486d
    ignoring (repeated crash)
06486d
06486d
- abrt-ccpp-hook crash
06486d
    Process 16223 (abrt-hook-ccpp) of user 1000 killed by SIGSEGV -
06486d
    ignoring (avoid recursion)
06486d
06486d
- abrt crash
06486d
    Process 16228 (abrt_test) of user 1000 killed by SIGSEGV -
06486d
    ignoring ('DebugLevel' == 0)
06486d
06486d
- not supported signal
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (unsupported signal)
06486d
06486d
- abrtd is not running
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (abrtd is not running)
06486d
06486d
- low free space
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (low free space)
06486d
06486d
- failed to parse /proc/$PID/status Uid
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (Failed to parse /proc/16229/status (Uid))
06486d
06486d
- failed to parse /proc/$PID/status Gid
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (Failed to parse /proc/16229/status (Gid))
06486d
06486d
- failed to get executable
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (Can't read /proc/16229/exe link)
06486d
06486d
- core size limit is bogus
06486d
    Process 16229 (crash) of user 1000 killed by signal 99 - ignoring
06486d
    (RLIMIT_CORE 'foo' is bogus)
06486d
06486d
I the case the crash is not ignored the log msg is following:
06486d
    Process 21768 (will_segfault) of user 1000 killed by SIGSEGV -
06486d
    dumping core
06486d
06486d
Related to: #1337186
06486d
06486d
Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
06486d
---
06486d
 src/hooks/abrt-hook-ccpp.c | 211 ++++++++++++++++++++++++++++-----------------
06486d
 1 file changed, 133 insertions(+), 78 deletions(-)
06486d
06486d
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
06486d
index 2c05c78..dc4dec6 100644
06486d
--- a/src/hooks/abrt-hook-ccpp.c
06486d
+++ b/src/hooks/abrt-hook-ccpp.c
06486d
@@ -695,7 +695,7 @@ static int test_configuration(bool setting_SaveFullCore, bool setting_CreateCore
06486d
     return 0;
06486d
 }
06486d
 
06486d
-static void error_msg_not_process_crash(const char *pid_str, const char *process_str,
06486d
+static void error_msg_process_crash(const char *pid_str, const char *process_str,
06486d
         long unsigned uid, int signal_no, const char *signame, const char *message, ...)
06486d
 {
06486d
     va_list p;
06486d
@@ -706,10 +706,10 @@ static void error_msg_not_process_crash(const char *pid_str, const char *process
06486d
     char *process_name = (process_str) ?  xasprintf(" (%s)", process_str) : xstrdup("");
06486d
 
06486d
     if (signame)
06486d
-        error_msg("Process %s (%s) of user %lu killed by SIG%s - %s", pid_str,
06486d
+        error_msg("Process %s%s of user %lu killed by SIG%s - %s", pid_str,
06486d
                         process_name, uid, signame, message_full);
06486d
     else
06486d
-        error_msg("Process %s (%s) of user %lu killed by signal %d - %s", pid_str,
06486d
+        error_msg("Process %s%s of user %lu killed by signal %d - %s", pid_str,
06486d
                         process_name, uid, signal_no, message_full);
06486d
 
06486d
     free(process_name);
06486d
@@ -718,6 +718,20 @@ static void error_msg_not_process_crash(const char *pid_str, const char *process
06486d
     return;
06486d
 }
06486d
 
06486d
+static void error_msg_ignore_crash(const char *pid_str, const char *process_str,
06486d
+        long unsigned uid, int signal_no, const char *signame, const char *message, ...)
06486d
+{
06486d
+    va_list p;
06486d
+    va_start(p, message);
06486d
+    char *message_full = xvasprintf(message, p);
06486d
+    va_end(p);
06486d
+
06486d
+    error_msg_process_crash(pid_str, process_str, uid, signal_no, signame, "ignoring (%s)", message_full);
06486d
+
06486d
+    free(message_full);
06486d
+    return;
06486d
+}
06486d
+
06486d
 int main(int argc, char** argv)
06486d
 {
06486d
     int err = 1;
06486d
@@ -798,24 +812,35 @@ int main(int argc, char** argv)
06486d
         }
06486d
     }
06486d
 
06486d
-    errno = 0;
06486d
     const char* signal_str = argv[1];
06486d
     int signal_no = xatoi_positive(signal_str);
06486d
     const char *signame = NULL;
06486d
     bool signal_is_fatal_bool = signal_is_fatal(signal_no, &signame);
06486d
+
06486d
+    const char *pid_str = argv[3];
06486d
+    /* xatoi_positive() handles errors */
06486d
+    uid_t uid = xatoi_positive(argv[4]);
06486d
+
06486d
+    errno = 0;
06486d
     off_t ulimit_c = strtoull(argv[2], NULL, 10);
06486d
+    if (errno)
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, NULL, (long unsigned)uid, signal_no,
06486d
+                signame, "RLIMIT_CORE '%s' is bogus", argv[2]);
06486d
+        xfunc_die();
06486d
+    }
06486d
+
06486d
     if (ulimit_c < 0) /* unlimited? */
06486d
     {
06486d
         /* set to max possible >0 value */
06486d
         ulimit_c = ~((off_t)1 << (sizeof(off_t)*8-1));
06486d
     }
06486d
-    const char *pid_str = argv[3];
06486d
-    pid_t local_pid = xatoi_positive(argv[3]);
06486d
-    uid_t uid = xatoi_positive(argv[4]);
06486d
-    if (errno || local_pid <= 0)
06486d
-    {
06486d
-        perror_msg_and_die("PID '%s' or limit '%s' is bogus", argv[3], argv[2]);
06486d
-    }
06486d
+
06486d
+    const char *global_pid_str = argv[8];
06486d
+    pid_t pid = xatoi_positive(argv[8]);
06486d
+
06486d
+    user_pwd = get_cwd(pid); /* may be NULL on error */
06486d
+    log_notice("user_pwd:'%s'", user_pwd);
06486d
 
06486d
     {
06486d
         char *s = xmalloc_fopen_fgetline_fclose(VAR_RUN"/abrt/saved_core_pattern");
06486d
@@ -825,8 +850,6 @@ int main(int argc, char** argv)
06486d
         else
06486d
             free(s);
06486d
     }
06486d
-    const char *global_pid_str = argv[8];
06486d
-    pid_t pid = xatoi_positive(argv[8]);
06486d
 
06486d
     pid_t tid = 0;
06486d
     if (argv[9])
06486d
@@ -836,56 +859,24 @@ int main(int argc, char** argv)
06486d
 
06486d
     char path[PATH_MAX];
06486d
 
06486d
-    int src_fd_binary = -1;
06486d
-    char *executable = get_executable(pid, setting_SaveBinaryImage ? &src_fd_binary : NULL);
06486d
-    if (executable == NULL)
06486d
-    {
06486d
-        error_msg_not_process_crash(pid_str, NULL, (long unsigned)uid, signal_no,
06486d
-                signame, "ignoring (can't read /proc/PID/exe link)");
06486d
-
06486d
-        xfunc_die();
06486d
-    }
06486d
-
06486d
-    if (strstr(executable, "/abrt-hook-ccpp"))
06486d
-    {
06486d
-        error_msg_and_die("PID %lu is '%s', not dumping it to avoid recursion",
06486d
-                        (long)pid, executable);
06486d
-    }
06486d
-
06486d
-    const char *last_slash = strrchr(executable, '/');
06486d
-    if (is_path_ignored(setting_ignored_paths, executable))
06486d
-    {
06486d
-        error_msg_not_process_crash(pid_str, last_slash + 1, (long unsigned)uid, signal_no,
06486d
-                signame, "ignoring (listed in 'IgnoredPaths')");
06486d
-
06486d
-        return 0;
06486d
-    }
06486d
-
06486d
-    /* dumping core for user, if allowed */
06486d
-    if (setting_allowed_users || setting_allowed_groups)
06486d
-    {
06486d
-        if (setting_allowed_users && is_user_allowed(uid, setting_allowed_users))
06486d
-            log_debug("User %lu is listed in 'AllowedUsers'", (long unsigned)uid);
06486d
-        else if (setting_allowed_groups && is_user_in_allowed_group(uid, setting_allowed_groups))
06486d
-            log_debug("User %lu is member of group listed in 'AllowedGroups'", (long unsigned)uid);
06486d
-        else
06486d
-        {
06486d
-            error_msg_not_process_crash(pid_str, last_slash + 1, (long unsigned)uid, signal_no,
06486d
-                signame, "ignoring (not allowed in 'AllowedUsers' nor 'AllowedGroups')");
06486d
-
06486d
-            xfunc_die();
06486d
-        }
06486d
-    }
06486d
-
06486d
-    user_pwd = get_cwd(pid);
06486d
-    log_notice("user_pwd:'%s'", user_pwd);
06486d
-
06486d
     sprintf(path, "/proc/%lu/status", (long)pid);
06486d
     char *proc_pid_status = xmalloc_xopen_read_close(path, /*maxsz:*/ NULL);
06486d
 
06486d
     uid_t fsuid = uid;
06486d
     uid_t tmp_fsuid = get_fsuid(proc_pid_status);
06486d
+    if (tmp_fsuid < 0)
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, NULL, (long unsigned)uid, signal_no,
06486d
+                signame, "Failed to parse /proc/%lu/status (Uid)", (long)pid);
06486d
+        xfunc_die();
06486d
+    }
06486d
     const int fsgid = get_fsgid(proc_pid_status);
06486d
+    if (fsgid < 0)
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, NULL, (long unsigned)uid, signal_no,
06486d
+                signame, "Failed to parse /proc/%lu/status (Gid)", (long)pid);
06486d
+        xfunc_die();
06486d
+    }
06486d
 
06486d
     int suid_policy = dump_suid_policy();
06486d
     if (tmp_fsuid != uid)
06486d
@@ -901,8 +892,7 @@ int main(int argc, char** argv)
06486d
         }
06486d
     }
06486d
 
06486d
-    /* If PrivateReports is on, root owns all problem directories */
06486d
-    const uid_t dduid = g_settings_privatereports ? 0 : fsuid;
06486d
+    snprintf(path, sizeof(path), "%s/last-ccpp", g_settings_dump_location);
06486d
 
06486d
     /* Open a fd to compat coredump, if requested and is possible */
06486d
     int user_core_fd = -1;
06486d
@@ -910,18 +900,72 @@ int main(int argc, char** argv)
06486d
         /* note: checks "user_pwd == NULL" inside; updates core_basename */
06486d
         user_core_fd = open_user_core(uid, fsuid, fsgid, pid, &argv[1]);
06486d
 
06486d
+    int src_fd_binary = -1;
06486d
+    char *executable = get_executable(pid, setting_SaveBinaryImage ? &src_fd_binary : NULL);
06486d
     if (executable == NULL)
06486d
     {
06486d
         /* readlink on /proc/$PID/exe failed, don't create abrt dump dir */
06486d
-        error_msg("Can't read /proc/%lu/exe link", (long)pid);
06486d
+        error_msg_ignore_crash(pid_str, NULL, (long unsigned)uid, signal_no,
06486d
+                signame, "Can't read /proc/%lu/exe link", (long)pid);
06486d
+
06486d
+        xfunc_die();
06486d
+    }
06486d
+
06486d
+    const char *last_slash = strrchr(executable, '/');
06486d
+    /* if the last_slash was found, skip it */
06486d
+    if (last_slash) ++last_slash;
06486d
+
06486d
+    if (is_path_ignored(setting_ignored_paths, executable))
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "listed in 'IgnoredPaths'");
06486d
+
06486d
+        return 0;
06486d
+    }
06486d
+
06486d
+    if (strstr(executable, "/abrt-hook-ccpp"))
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "avoid recursion");
06486d
+
06486d
+        xfunc_die();
06486d
+    }
06486d
+
06486d
+    /* Check /var/tmp/abrt/last-ccpp marker, do not dump repeated crashes
06486d
+     * if they happen too often. Else, write new marker value.
06486d
+     */
06486d
+    if (check_recent_crash_file(path, executable))
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "repeated crash");
06486d
+
06486d
+        /* It is a repeating crash */
06486d
         return create_user_core(user_core_fd, pid, ulimit_c);
06486d
     }
06486d
 
06486d
+    const bool abrt_crash = (last_slash && (strncmp(last_slash, "abrt", 4) == 0));
06486d
+    if (abrt_crash && g_settings_debug_level == 0)
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "'DebugLevel' == 0");
06486d
+
06486d
+        goto finito;
06486d
+    }
06486d
+
06486d
+    /* unsupported signal */
06486d
     if (!signal_is_fatal_bool)
06486d
+    {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "unsupported signal");
06486d
+
06486d
         return create_user_core(user_core_fd, pid, ulimit_c); // not a signal we care about
06486d
+    }
06486d
 
06486d
     if (!daemon_is_ok())
06486d
     {
06486d
+        error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "abrtd is not running");
06486d
+
06486d
         /* not an error, exit with exit code 0 */
06486d
         log("abrtd is not running. If it crashed, "
06486d
             "/proc/sys/kernel/core_pattern contains a stale value, "
06486d
@@ -930,32 +974,40 @@ int main(int argc, char** argv)
06486d
         return create_user_core(user_core_fd, pid, ulimit_c);
06486d
     }
06486d
 
06486d
+    /* dumping core for user, if allowed */
06486d
+    if (setting_allowed_users || setting_allowed_groups)
06486d
+    {
06486d
+        if (setting_allowed_users && is_user_allowed(uid, setting_allowed_users))
06486d
+            log_debug("User %lu is listed in 'AllowedUsers'", (long unsigned)uid);
06486d
+        else if (setting_allowed_groups && is_user_in_allowed_group(uid, setting_allowed_groups))
06486d
+            log_debug("User %lu is member of group listed in 'AllowedGroups'", (long unsigned)uid);
06486d
+        else
06486d
+        {
06486d
+            error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                signame, "not allowed in 'AllowedUsers' nor 'AllowedGroups'");
06486d
+
06486d
+            xfunc_die();
06486d
+        }
06486d
+    }
06486d
+
06486d
+    /* low free space */
06486d
     if (g_settings_nMaxCrashReportsSize > 0)
06486d
     {
06486d
         /* If free space is less than 1/4 of MaxCrashReportsSize... */
06486d
         if (low_free_space(g_settings_nMaxCrashReportsSize, g_settings_dump_location))
06486d
+        {
06486d
+            error_msg_ignore_crash(pid_str, last_slash, (long unsigned)uid, signal_no,
06486d
+                                    signame, "low free space");
06486d
             return create_user_core(user_core_fd, pid, ulimit_c);
06486d
+        }
06486d
     }
06486d
 
06486d
-    /* Check /var/tmp/abrt/last-ccpp marker, do not dump repeated crashes
06486d
-     * if they happen too often. Else, write new marker value.
06486d
-     */
06486d
-    snprintf(path, sizeof(path), "%s/last-ccpp", g_settings_dump_location);
06486d
-    if (check_recent_crash_file(path, executable))
06486d
-    {
06486d
-        /* It is a repeating crash */
06486d
-        return create_user_core(user_core_fd, pid, ulimit_c);
06486d
-    }
06486d
+    /* processing crash - inform user about it */
06486d
+    error_msg_process_crash(pid_str, last_slash, (long unsigned)uid,
06486d
+                signal_no, signame, "dumping core");
06486d
 
06486d
-    if (last_slash && strncmp(++last_slash, "abrt", 4) == 0)
06486d
+    if (abrt_crash)
06486d
     {
06486d
-        if (g_settings_debug_level == 0)
06486d
-        {
06486d
-            log_warning("Ignoring crash of %s (SIG%s).",
06486d
-                        executable, signame ? signame : signal_str);
06486d
-            goto finito;
06486d
-        }
06486d
-
06486d
         /* If abrtd/abrt-foo crashes, we don't want to create a _directory_,
06486d
          * since that can make new copy of abrtd to process it,
06486d
          * and maybe crash again...
06486d
@@ -974,7 +1026,7 @@ int main(int argc, char** argv)
06486d
              * but it does not log file name */
06486d
             error_msg_and_die("Error saving '%s'", path);
06486d
         }
06486d
-        log("Saved core dump of pid %lu (%s) to %s (%llu bytes)", (long)pid, executable, path, (long long)core_size);
06486d
+        log_notice("Saved core dump of pid %lu (%s) to %s (%llu bytes)", (long)pid, executable, path, (long long)core_size);
06486d
         err = 0;
06486d
         goto finito;
06486d
     }
06486d
@@ -986,6 +1038,9 @@ int main(int argc, char** argv)
06486d
         return create_user_core(user_core_fd, pid, ulimit_c);
06486d
     }
06486d
 
06486d
+    /* If PrivateReports is on, root owns all problem directories */
06486d
+    const uid_t dduid = g_settings_privatereports ? 0 : fsuid;
06486d
+
06486d
     /* use dduid (either fsuid or 0) instead of uid, so we don't expose any
06486d
      * sensitive information of suided app in /var/tmp/abrt
06486d
      *
06486d
-- 
06486d
1.8.3.1
06486d