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