Matej Habrnal fa1950
From e79b543156aec759542ca7aa01d727aea548f833 Mon Sep 17 00:00:00 2001
Matej Habrnal fa1950
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
Date: Wed, 20 May 2015 06:07:15 +0200
Matej Habrnal fa1950
Subject: [PATCH] ccpp: do not unlink failed and big user cores
Matej Habrnal fa1950
Matej Habrnal fa1950
* We might end up deleting an already existing file.
Matej Habrnal fa1950
* Kernel does not delete nor truncate core files. Admittedly, kernel
Matej Habrnal fa1950
  knows how process's memory is structured, dumps it per logical
Matej Habrnal fa1950
  segments and checks whether a next segment can be written.
Matej Habrnal fa1950
* 'ulimit -c' does not seem to be a hard limit. Kernel wrote 8192 bytes
Matej Habrnal fa1950
  despite $(ulimit -c) == 6.
Matej Habrnal fa1950
Matej Habrnal fa1950
Related: #1212818
Matej Habrnal fa1950
Matej Habrnal fa1950
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
---
Matej Habrnal fa1950
 src/hooks/abrt-hook-ccpp.c | 45 +++++++++++++++++----------------------------
Matej Habrnal fa1950
 1 file changed, 17 insertions(+), 28 deletions(-)
Matej Habrnal fa1950
Matej Habrnal fa1950
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
index 0448216..59fcfce 100644
Matej Habrnal fa1950
--- a/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
+++ b/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
@@ -117,8 +117,8 @@ static off_t copyfd_sparse(int src_fd, int dst_fd1, int dst_fd2, off_t size2)
Matej Habrnal fa1950
 		size2 -= rd;
Matej Habrnal fa1950
 		if (size2 < 0)
Matej Habrnal fa1950
 			dst_fd2 = -1;
Matej Habrnal fa1950
-//TODO: truncate to 0 or even delete the second file
Matej Habrnal fa1950
-//(currently we delete the file later)
Matej Habrnal fa1950
+// truncate to 0 or even delete the second file?
Matej Habrnal fa1950
+// No, kernel does not delete nor truncate core files.
Matej Habrnal fa1950
 	}
Matej Habrnal fa1950
  out:
Matej Habrnal fa1950
 
Matej Habrnal fa1950
@@ -377,13 +377,20 @@ static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char *
Matej Habrnal fa1950
 
Matej Habrnal fa1950
 user_core_fail:
Matej Habrnal fa1950
     if (user_core_fd >= 0)
Matej Habrnal fa1950
-    {
Matej Habrnal fa1950
         close(user_core_fd);
Matej Habrnal fa1950
-        unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
Matej Habrnal fa1950
-    }
Matej Habrnal fa1950
     return -1;
Matej Habrnal fa1950
 }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+static int close_user_core(int user_core_fd, off_t core_size)
Matej Habrnal fa1950
+{
Matej Habrnal fa1950
+    if (user_core_fd >= 0 && (fsync(user_core_fd) != 0 || close(user_core_fd) != 0 || core_size < 0))
Matej Habrnal fa1950
+    {
Matej Habrnal fa1950
+        perror_msg("Error writing '%s' at '%s'", core_basename, user_pwd);
Matej Habrnal fa1950
+        return -1;
Matej Habrnal fa1950
+    }
Matej Habrnal fa1950
+    return 0;
Matej Habrnal fa1950
+}
Matej Habrnal fa1950
+
Matej Habrnal fa1950
 /* Like xopen, but on error, unlocks and deletes dd and user core */
Matej Habrnal fa1950
 static int create_or_die(const char *filename, int user_core_fd)
Matej Habrnal fa1950
 {
Matej Habrnal fa1950
@@ -398,7 +405,7 @@ static int create_or_die(const char *filename, int user_core_fd)
Matej Habrnal fa1950
     if (dd)
Matej Habrnal fa1950
         dd_delete(dd);
Matej Habrnal fa1950
     if (user_core_fd >= 0)
Matej Habrnal fa1950
-        unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
Matej Habrnal fa1950
+        close(user_core_fd);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
     errno = sv_errno;
Matej Habrnal fa1950
     perror_msg_and_die("Can't open '%s'", filename);
Matej Habrnal fa1950
@@ -431,19 +438,10 @@ static int create_user_core(int user_core_fd, pid_t pid, off_t ulimit_c)
Matej Habrnal fa1950
     if (user_core_fd >= 0)
Matej Habrnal fa1950
     {
Matej Habrnal fa1950
         off_t core_size = copyfd_size(STDIN_FILENO, user_core_fd, ulimit_c, COPYFD_SPARSE);
Matej Habrnal fa1950
-        if (fsync(user_core_fd) != 0 || close(user_core_fd) != 0 || core_size < 0)
Matej Habrnal fa1950
-        {
Matej Habrnal fa1950
-            /* perror first, otherwise unlink may trash errno */
Matej Habrnal fa1950
-            perror_msg("Error writing '%s' at '%s'", core_basename, user_pwd);
Matej Habrnal fa1950
-            unlinkat(dirfd(proc_cwd), core_basename, /*only files*/0);
Matej Habrnal fa1950
-            goto finito;
Matej Habrnal fa1950
-        }
Matej Habrnal fa1950
-        if (ulimit_c == 0 || core_size > ulimit_c)
Matej Habrnal fa1950
-        {
Matej Habrnal fa1950
-            unlinkat(dirfd(proc_cwd), core_basename, /*only files*/0);
Matej Habrnal fa1950
+        if (close_user_core(user_core_fd, core_size) != 0)
Matej Habrnal fa1950
             goto finito;
Matej Habrnal fa1950
-        }
Matej Habrnal fa1950
-        log_notice("Saved core dump of pid %lu to %s at '%s' (%llu bytes)", (long)pid, core_basename, user_pwd, (long long)core_size);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        log_notice("Saved core dump of pid %lu to '%s' at '%s' (%llu bytes)", (long)pid, core_basename, user_pwd, (long long)core_size);
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
     err = 0;
Matej Habrnal fa1950
 
Matej Habrnal fa1950
@@ -822,6 +820,7 @@ int main(int argc, char** argv)
Matej Habrnal fa1950
              * ls: cannot access core*: No such file or directory <=== BAD
Matej Habrnal fa1950
              */
Matej Habrnal fa1950
             core_size = copyfd_sparse(STDIN_FILENO, abrt_core_fd, user_core_fd, ulimit_c);
Matej Habrnal fa1950
+            close_user_core(user_core_fd, core_size);
Matej Habrnal fa1950
             if (fsync(abrt_core_fd) != 0 || close(abrt_core_fd) != 0 || core_size < 0)
Matej Habrnal fa1950
             {
Matej Habrnal fa1950
                 unlink(path);
Matej Habrnal fa1950
@@ -832,16 +831,6 @@ int main(int argc, char** argv)
Matej Habrnal fa1950
 
Matej Habrnal fa1950
                 goto cleanup_and_exit;
Matej Habrnal fa1950
             }
Matej Habrnal fa1950
-            if (user_core_fd >= 0
Matej Habrnal fa1950
-                /* error writing user coredump? */
Matej Habrnal fa1950
-             && (fsync(user_core_fd) != 0 || close(user_core_fd) != 0
Matej Habrnal fa1950
-                /* user coredump is too big? */
Matej Habrnal fa1950
-                || (ulimit_c == 0 /* paranoia */ || core_size > ulimit_c)
Matej Habrnal fa1950
-                )
Matej Habrnal fa1950
-            ) {
Matej Habrnal fa1950
-                /* nuke it (silently) */
Matej Habrnal fa1950
-                unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
Matej Habrnal fa1950
-            }
Matej Habrnal fa1950
         }
Matej Habrnal fa1950
         else
Matej Habrnal fa1950
         {
Matej Habrnal fa1950
-- 
Matej Habrnal fa1950
2.1.0
Matej Habrnal fa1950