#include <stdio.h>
#include <sys/prctl.h>
#include <sys/types.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <systemd/sd-journal.h>
#include <systemd/sd-login.h>
#include "conf-parser.h"
#include "copy.h"
#include "stacktrace.h"
+#include "path-util.h"
#ifdef HAVE_ACL
#include <sys/acl.h>
}
static int fix_xattr(int fd, char *argv[]) {
+
+ static const char * const xattrs[_ARG_MAX] = {
+ [ARG_PID] = "user.coredump.pid",
+ [ARG_UID] = "user.coredump.uid",
+ [ARG_GID] = "user.coredump.gid",
+ [ARG_SIGNAL] = "user.coredump.signal",
+ [ARG_TIMESTAMP] = "user.coredump.timestamp",
+ [ARG_COMM] = "user.coredump.comm",
+ };
+
int r = 0;
+ unsigned i;
/* Attach some metadate to coredumps via extended
* attributes. Just because we can. */
- if (!isempty(argv[ARG_PID]))
- if (fsetxattr(fd, "user.coredump.pid", argv[ARG_PID], strlen(argv[ARG_PID]), XATTR_CREATE) < 0)
- r = -errno;
-
- if (!isempty(argv[ARG_UID]))
- if (fsetxattr(fd, "user.coredump.uid", argv[ARG_UID], strlen(argv[ARG_UID]), XATTR_CREATE) < 0)
- r = -errno;
-
- if (!isempty(argv[ARG_GID]))
- if (fsetxattr(fd, "user.coredump.gid", argv[ARG_GID], strlen(argv[ARG_GID]), XATTR_CREATE) < 0)
- r = -errno;
-
- if (!isempty(argv[ARG_SIGNAL]))
- if (fsetxattr(fd, "user.coredump.signal", argv[ARG_SIGNAL], strlen(argv[ARG_SIGNAL]), XATTR_CREATE) < 0)
- r = -errno;
+ for (i = 0; i < _ARG_MAX; i++) {
+ if (isempty(argv[i]))
+ continue;
- if (!isempty(argv[ARG_TIMESTAMP]))
- if (fsetxattr(fd, "user.coredump.timestamp", argv[ARG_TIMESTAMP], strlen(argv[ARG_TIMESTAMP]), XATTR_CREATE) < 0)
- r = -errno;
-
- if (!isempty(argv[ARG_COMM]))
- if (fsetxattr(fd, "user.coredump.comm", argv[ARG_COMM], strlen(argv[ARG_COMM]), XATTR_CREATE) < 0)
+ if (fsetxattr(fd, xattrs[i], argv[i], strlen(argv[i]), XATTR_CREATE) < 0)
r = -errno;
+ }
return r;
}
-#define filename_escape(s) xescape((s), "./")
+#define filename_escape(s) xescape((s), "./ ")
static int save_external_coredump(char **argv, uid_t uid, char **ret_filename, int *ret_fd, off_t *ret_size) {
_cleanup_free_ char *p = NULL, *t = NULL, *c = NULL, *fn = NULL, *tmp = NULL;
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;
}
parse_config();
log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage));
+ /* Exit early if we cannot write the coredump to disk anyway */
+ if (path_is_read_only_fs("/var/lib") != 0) {
+ log_error("Coredump directory not mounted or not writable, skipping coredump.");
+ r = -EROFS;
+ goto finish;
+ }
+
r = parse_uid(argv[ARG_UID], &uid);
if (r < 0) {
log_error("Failed to parse UID.");