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