diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/journal/coredump.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/src/journal/coredump.c b/src/journal/coredump.c index bbec550784..6b8809972d 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -45,6 +45,8 @@ int main(int argc, char* argv[]) { char *p = NULL; ssize_t n; pid_t pid; + uid_t uid; + gid_t gid; struct iovec iovec[14]; 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, @@ -63,31 +65,21 @@ int main(int argc, char* argv[]) { r = parse_pid(argv[ARG_PID], &pid); if (r < 0) { log_error("Failed to parse PID."); - r = -EINVAL; goto finish; } - p = malloc(9 + COREDUMP_MAX); - if (!p) { - log_error("Out of memory"); - r = -ENOMEM; + r = parse_uid(argv[ARG_UID], &uid); + if (r < 0) { + log_error("Failed to parse UID."); goto finish; } - memcpy(p, "COREDUMP=", 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; + r = parse_gid(argv[ARG_GID], &gid); + if (r < 0) { + log_error("Failed to parse GID."); goto finish; } - zero(iovec); - iovec[j].iov_base = p; - iovec[j].iov_len = 9 + n; - j++; - core_pid = strappend("COREDUMP_PID=", argv[ARG_PID]); if (core_pid) IOVEC_SET_STRING(iovec[j++], core_pid); @@ -151,6 +143,39 @@ int main(int argc, char* argv[]) { if (core_message) IOVEC_SET_STRING(iovec[j++], core_message); + /* Now, let's drop privileges to become the user who owns the + * segfaulted process and allocate the coredump memory under + * his uid. This also ensures that the credentials journald + * will see are the ones of the coredumping user, thus making + * sure the user himself gets access to the core dump. */ + + if (setresgid(gid, gid, gid) < 0 || + setresuid(uid, uid, uid) < 0) { + log_error("Failed to drop privileges: %m"); + r = -errno; + goto finish; + } + + p = malloc(9 + COREDUMP_MAX); + if (!p) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + memcpy(p, "COREDUMP=", 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; + } + + iovec[j].iov_base = p; + iovec[j].iov_len = 9 + n; + j++; + r = sd_journal_sendv(iovec, j); if (r < 0) log_error("Failed to send coredump: %s", strerror(-r)); |