diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/journal/coredump.c | 10 | ||||
-rw-r--r-- | src/journal/coredumpctl.c | 2 | ||||
-rw-r--r-- | src/shared/copy.c | 25 | ||||
-rw-r--r-- | src/shared/copy.h | 2 | ||||
-rw-r--r-- | src/sysusers/sysusers.c | 2 |
5 files changed, 32 insertions, 9 deletions
diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 764c5e72ab..1b35eb1698 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -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; } diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index fefd02bc9b..48e63415b1 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -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; diff --git a/src/shared/copy.c b/src/shared/copy.c index 7c3fab6901..ebd6699838 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -22,15 +22,27 @@ #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; diff --git a/src/shared/copy.h b/src/shared/copy.h index 1d5e0adc53..0bf2598f60 100644 --- a/src/shared/copy.h +++ b/src/shared/copy.h @@ -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); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index d549969ff2..c192add61f 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -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; |