X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fcoredump.c;h=733373b3071d16a70710aa19e9f034ae181bf729;hb=26fefda707e6511733f48da03b281a004dba6abf;hp=021b4c665187b0998463b849bd3e3c6b029d5fa0;hpb=b7f7c68570b384fceceb82660528e688f207e145;p=elogind.git diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 021b4c665..733373b30 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -37,7 +37,11 @@ #include "special.h" #include "cgroup-util.h" -#define COREDUMP_MAX (24*1024*1024) +/* Few programs have less than 3MiB resident */ +#define COREDUMP_MIN_START (3*1024*1024) +/* Make sure to not make this larger than the maximum journal entry + * size. See ENTRY_SIZE_MAX in journald-native.c. */ +#define COREDUMP_MAX (767*1024*1024) enum { ARG_PID = 1, @@ -95,15 +99,16 @@ static int divert_coredump(void) { int main(int argc, char* argv[]) { int r, j = 0; - _cleanup_free_ char *p = NULL; + char *t; ssize_t n; pid_t pid; uid_t uid; gid_t gid; struct iovec iovec[14]; + size_t coredump_bufsize, coredump_size; _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, - *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t = NULL; + *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *coredump_data = NULL; prctl(PR_SET_DUMPABLE, 0); @@ -232,28 +237,47 @@ int main(int argc, char* argv[]) { goto finish; } - p = malloc(9 + COREDUMP_MAX); - if (!p) { - r = log_oom(); - goto finish; + coredump_bufsize = COREDUMP_MIN_START; + coredump_data = malloc(coredump_bufsize); + if (!coredump_data) { + log_warning("Failed to allocate memory for core, core will not be stored."); + goto finalize; } - memcpy(p, "COREDUMP=", 9); + memcpy(coredump_data, "COREDUMP=", 9); + coredump_size = 9; - n = loop_read(STDIN_FILENO, p + 9, COREDUMP_MAX, false); - if (n < 0) { - log_error("Failed to read core dump data: %s", strerror(-n)); - r = (int) n; - goto finish; + for (;;) { + n = loop_read(STDIN_FILENO, coredump_data + coredump_size, + coredump_bufsize - coredump_size, false); + if (n < 0) { + log_error("Failed to read core data: %s", strerror(-n)); + r = (int) n; + goto finish; + } else if (n == 0) + break; + + coredump_size += n; + + if (coredump_size > COREDUMP_MAX) { + log_error("Core too large, core will not be stored."); + goto finalize; + } + + if (!GREEDY_REALLOC(coredump_data, coredump_bufsize, coredump_size + 1)) { + log_warning("Failed to allocate memory for core, core will not be stored."); + goto finalize; + } } - iovec[j].iov_base = p; - iovec[j].iov_len = 9 + n; + iovec[j].iov_base = coredump_data; + iovec[j].iov_len = coredump_size; j++; +finalize: r = sd_journal_sendv(iovec, j); if (r < 0) - log_error("Failed to send coredump: %s", strerror(-r)); + log_error("Failed to log coredump: %s", strerror(-r)); finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;