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

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