chiark / gitweb /
coredump: never write more than the configured processing size limit to disk
authorLennart Poettering <lennart@poettering.net>
Mon, 23 Jun 2014 14:28:05 +0000 (16:28 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 23 Jun 2014 14:28:05 +0000 (16:28 +0200)
src/journal/coredump.c
src/journal/coredumpctl.c
src/shared/copy.c
src/shared/copy.h
src/sysusers/sysusers.c

index 764c5e7..1b35eb1 100644 (file)
@@ -240,8 +240,14 @@ static int save_external_coredump(char **argv, uid_t uid, char **ret_filename, i
                 return -errno;
         }
 
-        r = copy_bytes(STDIN_FILENO, fd);
-        if (r < 0) {
+        r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
+        if (r == -E2BIG) {
+                log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", argv[ARG_PID], argv[ARG_COMM]);
+                goto fail;
+        } else if (IN_SET(r, -EDQUOT, -ENOSPC)) {
+                log_error("Not enough disk space for coredump of %s (%s), refusing.", argv[ARG_PID], argv[ARG_COMM]);
+                goto fail;
+        } else if (r < 0) {
                 log_error("Failed to dump coredump to file: %s", strerror(-r));
                 goto fail;
         }
index fefd02b..48e6341 100644 (file)
@@ -659,7 +659,7 @@ static int dump_core(sd_journal* j) {
                         return -errno;
                 }
 
-                r = copy_bytes(fd, output ? fileno(output) : STDOUT_FILENO);
+                r = copy_bytes(fd, output ? fileno(output) : STDOUT_FILENO, (off_t) -1);
                 if (r < 0) {
                         log_error("Failed to stream coredump: %s", strerror(-r));
                         return r;
index 7c3fab6..ebd6699 100644 (file)
 #include "util.h"
 #include "copy.h"
 
-int copy_bytes(int fdf, int fdt) {
+int copy_bytes(int fdf, int fdt, off_t max_bytes) {
         assert(fdf >= 0);
         assert(fdt >= 0);
 
         for (;;) {
                 char buf[PIPE_BUF];
                 ssize_t n, k;
+                size_t m;
 
-                n = read(fdf, buf, sizeof(buf));
+                m = sizeof(buf);
+
+                if (max_bytes != (off_t) -1) {
+
+                        if (max_bytes <= 0)
+                                return -E2BIG;
+
+                        if ((off_t) m > max_bytes)
+                                m = (size_t) max_bytes;
+                }
+
+                n = read(fdf, buf, m);
                 if (n < 0)
                         return -errno;
                 if (n == 0)
@@ -42,6 +54,11 @@ int copy_bytes(int fdf, int fdt) {
                         return k;
                 if (k != n)
                         return errno ? -errno : -EIO;
+
+                if (max_bytes != (off_t) -1) {
+                        assert(max_bytes >= n);
+                        max_bytes -= n;
+                }
         }
 
         return 0;
@@ -84,7 +101,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
         if (fdt < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt);
+        r = copy_bytes(fdf, fdt, (off_t) -1);
         if (r < 0) {
                 unlinkat(dt, to, 0);
                 return r;
@@ -262,7 +279,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode) {
         if (fdt < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt);
+        r = copy_bytes(fdf, fdt, (off_t) -1);
         if (r < 0) {
                 unlink(to);
                 return r;
index 1d5e0ad..0bf2598 100644 (file)
@@ -23,4 +23,4 @@
 
 int copy_file(const char *from, const char *to, int flags, mode_t mode);
 int copy_tree(const char *from, const char *to, bool merge);
-int copy_bytes(int fdf, int fdt);
+int copy_bytes(int fdf, int fdt, off_t max_bytes);
index d549969..c192add 100644 (file)
@@ -211,7 +211,7 @@ static int make_backup(const char *x) {
         if (dst < 0)
                 return dst;
 
-        r = copy_bytes(src, dst);
+        r = copy_bytes(src, dst, (off_t) -1);
         if (r < 0)
                 goto fail;