From a73c74db66a14540eb043bf9535c0d9c37804062 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Jun 2023 16:48:48 +0200 Subject: [PATCH 1/3] coredump: use loop_read() for reading coredump into memory Fixes: #26748 --- src/basic/io-util.c | 3 +-- src/coredump/coredump.c | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/basic/io-util.c b/src/basic/io-util.c index 6f6fb8068c..bf1aab9e38 100644 --- a/src/basic/io-util.c +++ b/src/basic/io-util.c @@ -54,8 +54,7 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { assert(fd >= 0); - /* If called with nbytes == 0, let's call read() at least - * once, to validate the operation */ + /* If called with nbytes == 0, let's call read() at least once, to validate the operation */ if (nbytes > (size_t) SSIZE_MAX) return -EINVAL; diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 847ac531df..940c0def61 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -604,14 +604,15 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s return log_warning_errno(errno, "Failed to seek: %m"); field = malloc(9 + size); - if (!field) { - log_warning("Failed to allocate memory for coredump, coredump will not be stored."); - return -ENOMEM; - } + if (!field) + return log_warning_errno(SYNTHETIC_ERRNO(ENOMEM), + "Failed to allocate memory for coredump, coredump will not be stored."); memcpy(field, "COREDUMP=", 9); - n = read(fd, field + 9, size); + /* NB: simple read() would fail for overly large coredumps, since read() on Linux can only deal with + * 0x7ffff000 bytes max. Hence call things in a loop. */ + n = loop_read(fd, field + 9, size, /* do_poll= */ false); if (n < 0) return log_error_errno((int) n, "Failed to read core data: %m"); if ((size_t) n < size) From 4a78074fc14c684600f2bbdac7b5bb13325aba39 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Jun 2023 17:11:00 +0200 Subject: [PATCH 2/3] coredump: clamp JournalSizeMax= to maximum journald would accept See: #26748 --- src/coredump/coredump.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 940c0def61..39b777b535 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -172,9 +172,27 @@ static int parse_config(void) { {} }; - return config_parse_config_file("coredump.conf", "Coredump\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + int r; + + r = config_parse_config_file( + "coredump.conf", + "Coredump\0", + config_item_table_lookup, + items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); + if (r < 0) + return r; + + /* Let's make sure we fix up the maximum size we send to the journal here on the client side, for + * efficiency reasons. journald wouldn't accept anything larger anyway. */ + if (arg_journal_size_max > JOURNAL_SIZE_MAX) { + log_warning("JournalSizeMax= set to larger value (%s) than journald would accept (%s), lowering automatically.", + FORMAT_BYTES(arg_journal_size_max), FORMAT_BYTES(JOURNAL_SIZE_MAX)); + arg_journal_size_max = JOURNAL_SIZE_MAX; + } + + return 0; } static uint64_t storage_size_max(void) { From e6421b6ccd4677d22380d3f3dcb688ec9e347784 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Jun 2023 17:10:14 +0200 Subject: [PATCH 3/3] man: correct and extend JournalSizeMax= The man page claimed the default was 10M, but that's not true, it's 767M. Also mention there's no point in increasing it further. See: #26748 --- man/coredump.conf.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml index 7cb71f80aa..7a617b1985 100644 --- a/man/coredump.conf.xml +++ b/man/coredump.conf.xml @@ -97,11 +97,14 @@ ExternalSizeMax= JournalSizeMax= - The maximum (compressed or uncompressed) size in bytes of a core to be saved in - separate files on disk (default: 1G on 32bit, 32G on 64bit systems) or in the journal (default: - 10M). Unit suffixes are allowed just as in . + The maximum (compressed or uncompressed) size in bytes of a coredump to be saved in + separate files on disk (default: 1G on 32-bit systems, 32G on 64-bit systems) or in the journal + (default: 767M). Note that the journal service enforces a hard limit on journal log records of 767M, + and will ignore larger submitted log records. Hence, JournalSizeMax= may be + lowered relative to the default, but not increased. Unit suffixes are allowed just as in + . - ExternalSizeMax=infinity sets the core size to unlimited. + ExternalSizeMax=infinity sets the core size to unlimited.