|
|
8ec399 |
From 7bd77a63f226a572946f30db3e76f23f971f46d5 Mon Sep 17 00:00:00 2001
|
|
|
8ec399 |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
8ec399 |
Date: Wed, 20 May 2015 06:07:15 +0200
|
|
|
8ec399 |
Subject: [ABRT PATCH] ccpp: do not unlink failed and big user cores
|
|
|
8ec399 |
|
|
|
8ec399 |
* We might end up deleting an already existing file.
|
|
|
8ec399 |
* Kernel does not delete nor truncate core files. Admittedly, kernel
|
|
|
8ec399 |
knows how process's memory is structured, dumps it per logical
|
|
|
8ec399 |
segments and checks whether a next segment can be written.
|
|
|
8ec399 |
* 'ulimit -c' does not seem to be a hard limit. Kernel wrote 8192 bytes
|
|
|
8ec399 |
despite $(ulimit -c) == 6.
|
|
|
8ec399 |
|
|
|
8ec399 |
Related: #1212818
|
|
|
8ec399 |
|
|
|
8ec399 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
8ec399 |
---
|
|
|
8ec399 |
src/hooks/abrt-hook-ccpp.c | 70 +++++++++++++++++++---------------------------
|
|
|
8ec399 |
1 file changed, 29 insertions(+), 41 deletions(-)
|
|
|
8ec399 |
|
|
|
8ec399 |
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
|
|
|
8ec399 |
index fdd9b06..9b38ed7 100644
|
|
|
8ec399 |
--- a/src/hooks/abrt-hook-ccpp.c
|
|
|
8ec399 |
+++ b/src/hooks/abrt-hook-ccpp.c
|
|
|
8ec399 |
@@ -129,8 +129,8 @@ static off_t copyfd_sparse(int src_fd, int dst_fd1, int dst_fd2, off_t size2)
|
|
|
8ec399 |
size2 -= rd;
|
|
|
8ec399 |
if (size2 < 0)
|
|
|
8ec399 |
dst_fd2 = -1;
|
|
|
8ec399 |
-//TODO: truncate to 0 or even delete the second file
|
|
|
8ec399 |
-//(currently we delete the file later)
|
|
|
8ec399 |
+// truncate to 0 or even delete the second file?
|
|
|
8ec399 |
+// No, kernel does not delete nor truncate core files.
|
|
|
8ec399 |
}
|
|
|
8ec399 |
out:
|
|
|
8ec399 |
|
|
|
8ec399 |
@@ -502,13 +502,20 @@ static int open_user_core(uid_t uid, uid_t fsuid, pid_t pid, char **percent_valu
|
|
|
8ec399 |
|
|
|
8ec399 |
user_core_fail:
|
|
|
8ec399 |
if (user_core_fd >= 0)
|
|
|
8ec399 |
- {
|
|
|
8ec399 |
close(user_core_fd);
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
- }
|
|
|
8ec399 |
return -1;
|
|
|
8ec399 |
}
|
|
|
8ec399 |
|
|
|
8ec399 |
+static int close_user_core(int user_core_fd, off_t core_size)
|
|
|
8ec399 |
+{
|
|
|
8ec399 |
+ if (user_core_fd >= 0 && (fsync(user_core_fd) != 0 || close(user_core_fd) != 0 || core_size < 0))
|
|
|
8ec399 |
+ {
|
|
|
8ec399 |
+ perror_msg("Error writing '%s' at '%s'", core_basename, user_pwd);
|
|
|
8ec399 |
+ return -1;
|
|
|
8ec399 |
+ }
|
|
|
8ec399 |
+ return 0;
|
|
|
8ec399 |
+}
|
|
|
8ec399 |
+
|
|
|
8ec399 |
static bool dump_fd_info(const char *dest_filename, char *source_filename, int source_base_ofs, uid_t uid, gid_t gid)
|
|
|
8ec399 |
{
|
|
|
8ec399 |
FILE *fp = fopen(dest_filename, "wx");
|
|
|
8ec399 |
@@ -569,7 +576,7 @@ static int create_or_die(const char *filename)
|
|
|
8ec399 |
if (dd)
|
|
|
8ec399 |
dd_delete(dd);
|
|
|
8ec399 |
if (user_core_fd >= 0)
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
+ close(user_core_fd);
|
|
|
8ec399 |
|
|
|
8ec399 |
errno = sv_errno;
|
|
|
8ec399 |
perror_msg_and_die("Can't open '%s'", filename);
|
|
|
8ec399 |
@@ -577,6 +584,7 @@ static int create_or_die(const char *filename)
|
|
|
8ec399 |
|
|
|
8ec399 |
int main(int argc, char** argv)
|
|
|
8ec399 |
{
|
|
|
8ec399 |
+ int err = 1;
|
|
|
8ec399 |
/* Kernel starts us with all fd's closed.
|
|
|
8ec399 |
* But it's dangerous:
|
|
|
8ec399 |
* fprintf(stderr) can dump messages into random fds, etc.
|
|
|
8ec399 |
@@ -778,9 +786,8 @@ int main(int argc, char** argv)
|
|
|
8ec399 |
error_msg_and_die("Error saving '%s'", path);
|
|
|
8ec399 |
}
|
|
|
8ec399 |
log("Saved core dump of pid %lu (%s) to %s (%llu bytes)", (long)pid, executable, path, (long long)core_size);
|
|
|
8ec399 |
- if (proc_cwd != NULL)
|
|
|
8ec399 |
- closedir(proc_cwd);
|
|
|
8ec399 |
- return 0;
|
|
|
8ec399 |
+ err = 0;
|
|
|
8ec399 |
+ goto finito;
|
|
|
8ec399 |
}
|
|
|
8ec399 |
|
|
|
8ec399 |
unsigned path_len = snprintf(path, sizeof(path), "%s/ccpp-%s-%lu.new",
|
|
|
8ec399 |
@@ -895,26 +902,17 @@ int main(int argc, char** argv)
|
|
|
8ec399 |
* ls: cannot access core*: No such file or directory <=== BAD
|
|
|
8ec399 |
*/
|
|
|
8ec399 |
off_t core_size = copyfd_sparse(STDIN_FILENO, abrt_core_fd, user_core_fd, ulimit_c);
|
|
|
8ec399 |
+
|
|
|
8ec399 |
+ close_user_core(user_core_fd, core_size);
|
|
|
8ec399 |
+
|
|
|
8ec399 |
if (fsync(abrt_core_fd) != 0 || close(abrt_core_fd) != 0 || core_size < 0)
|
|
|
8ec399 |
{
|
|
|
8ec399 |
unlink(path);
|
|
|
8ec399 |
dd_delete(dd);
|
|
|
8ec399 |
- if (user_core_fd >= 0)
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
/* copyfd_sparse logs the error including errno string,
|
|
|
8ec399 |
* but it does not log file name */
|
|
|
8ec399 |
error_msg_and_die("Error writing '%s'", path);
|
|
|
8ec399 |
}
|
|
|
8ec399 |
- if (user_core_fd >= 0
|
|
|
8ec399 |
- /* error writing user coredump? */
|
|
|
8ec399 |
- && (fsync(user_core_fd) != 0 || close(user_core_fd) != 0
|
|
|
8ec399 |
- /* user coredump is too big? */
|
|
|
8ec399 |
- || (ulimit_c == 0 /* paranoia */ || core_size > ulimit_c)
|
|
|
8ec399 |
- )
|
|
|
8ec399 |
- ) {
|
|
|
8ec399 |
- /* nuke it (silently) */
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
- }
|
|
|
8ec399 |
|
|
|
8ec399 |
/* Because of #1211835 and #1126850 */
|
|
|
8ec399 |
#if 0
|
|
|
8ec399 |
@@ -984,9 +982,9 @@ int main(int argc, char** argv)
|
|
|
8ec399 |
}
|
|
|
8ec399 |
|
|
|
8ec399 |
free(rootdir);
|
|
|
8ec399 |
- if (proc_cwd != NULL)
|
|
|
8ec399 |
- closedir(proc_cwd);
|
|
|
8ec399 |
- return 0;
|
|
|
8ec399 |
+
|
|
|
8ec399 |
+ err = 0;
|
|
|
8ec399 |
+ goto finito;
|
|
|
8ec399 |
}
|
|
|
8ec399 |
|
|
|
8ec399 |
/* We didn't create abrt dump, but may need to create compat coredump */
|
|
|
8ec399 |
@@ -994,26 +992,16 @@ int main(int argc, char** argv)
|
|
|
8ec399 |
if (user_core_fd >= 0)
|
|
|
8ec399 |
{
|
|
|
8ec399 |
off_t core_size = copyfd_size(STDIN_FILENO, user_core_fd, ulimit_c, COPYFD_SPARSE);
|
|
|
8ec399 |
- if (fsync(user_core_fd) != 0 || close(user_core_fd) != 0 || core_size < 0)
|
|
|
8ec399 |
- {
|
|
|
8ec399 |
- /* perror first, otherwise unlink may trash errno */
|
|
|
8ec399 |
- perror_msg("Error writing '%s' at '%s'", core_basename, user_pwd);
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
- if (proc_cwd != NULL)
|
|
|
8ec399 |
- closedir(proc_cwd);
|
|
|
8ec399 |
- return 1;
|
|
|
8ec399 |
- }
|
|
|
8ec399 |
- if (ulimit_c == 0 || core_size > ulimit_c)
|
|
|
8ec399 |
- {
|
|
|
8ec399 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
|
8ec399 |
- if (proc_cwd != NULL)
|
|
|
8ec399 |
- closedir(proc_cwd);
|
|
|
8ec399 |
- return 1;
|
|
|
8ec399 |
- }
|
|
|
8ec399 |
+ if (close_user_core(user_core_fd, core_size) != 0)
|
|
|
8ec399 |
+ goto finito;
|
|
|
8ec399 |
+
|
|
|
8ec399 |
+ err = 0;
|
|
|
8ec399 |
log("Saved core dump of pid %lu to %s at %s (%llu bytes)", (long)pid, core_basename, user_pwd, (long long)core_size);
|
|
|
8ec399 |
}
|
|
|
8ec399 |
|
|
|
8ec399 |
+ finito:
|
|
|
8ec399 |
if (proc_cwd != NULL)
|
|
|
8ec399 |
closedir(proc_cwd);
|
|
|
8ec399 |
- return 0;
|
|
|
8ec399 |
+
|
|
|
8ec399 |
+ return err;
|
|
|
8ec399 |
}
|
|
|
8ec399 |
--
|
|
|
8ec399 |
1.8.3.1
|
|
|
8ec399 |
|