]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/coredump/coredump.c
tree-wide: use memstream-util
[thirdparty/systemd.git] / src / coredump / coredump.c
index 1f259cf669bad995591de5514a9454fc6a242bbe..b355970f0ffa61b27eed8f12dd23280b2d990f27 100644 (file)
@@ -36,6 +36,7 @@
 #include "macro.h"
 #include "main-func.h"
 #include "memory-util.h"
+#include "memstream-util.h"
 #include "mkdir-label.h"
 #include "parse-util.h"
 #include "process-util.h"
@@ -49,7 +50,6 @@
 #include "sync-util.h"
 #include "tmpfile-util.h"
 #include "uid-alloc-range.h"
-#include "unaligned.h"
 #include "user-util.h"
 
 /* The maximum size up to which we process coredumps. We use 1G on 32bit systems, and 32G on 64bit systems */
@@ -336,66 +336,6 @@ static int make_filename(const Context *context, char **ret) {
         return 0;
 }
 
-#define _DEFINE_PARSE_AUXV(size, type, unaligned_read)                  \
-        static int parse_auxv##size(                                    \
-                        const void *auxv,                               \
-                        size_t size_bytes,                              \
-                        int *at_secure,                                 \
-                        uid_t *uid,                                     \
-                        uid_t *euid,                                    \
-                        gid_t *gid,                                     \
-                        gid_t *egid) {                                  \
-                                                                        \
-                assert(auxv || size_bytes == 0);                        \
-                                                                        \
-                if (size_bytes % (2 * sizeof(type)) != 0)               \
-                        return log_warning_errno(SYNTHETIC_ERRNO(EIO),  \
-                                                 "Incomplete auxv structure (%zu bytes).", \
-                                                 size_bytes);           \
-                                                                        \
-                size_t words = size_bytes / sizeof(type);               \
-                                                                        \
-                /* Note that we set output variables even on error. */  \
-                                                                        \
-                for (size_t i = 0; i + 1 < words; i += 2) {             \
-                        type key, val;                                  \
-                                                                        \
-                        key = unaligned_read((uint8_t*) auxv + i * sizeof(type)); \
-                        val = unaligned_read((uint8_t*) auxv + (i + 1) * sizeof(type)); \
-                                                                        \
-                        switch (key) {                                  \
-                        case AT_SECURE:                                 \
-                                *at_secure = val != 0;                  \
-                                break;                                  \
-                        case AT_UID:                                    \
-                                *uid = val;                             \
-                                break;                                  \
-                        case AT_EUID:                                   \
-                                *euid = val;                            \
-                                break;                                  \
-                        case AT_GID:                                    \
-                                *gid = val;                             \
-                                break;                                  \
-                        case AT_EGID:                                   \
-                                *egid = val;                            \
-                                break;                                  \
-                        case AT_NULL:                                   \
-                                if (val != 0)                           \
-                                        goto error;                     \
-                                return 0;                               \
-                        }                                               \
-                }                                                       \
-        error:                                                          \
-                return log_warning_errno(SYNTHETIC_ERRNO(ENODATA),      \
-                                         "AT_NULL terminator not found, cannot parse auxv structure."); \
-        }
-
-#define DEFINE_PARSE_AUXV(size)\
-        _DEFINE_PARSE_AUXV(size, uint##size##_t, unaligned_read_ne##size)
-
-DEFINE_PARSE_AUXV(32);
-DEFINE_PARSE_AUXV(64);
-
 static int grant_user_access(int core_fd, const Context *context) {
         int at_secure = -1;
         uid_t uid = UID_INVALID, euid = UID_INVALID;
@@ -430,14 +370,11 @@ static int grant_user_access(int core_fd, const Context *context) {
                 return log_info_errno(SYNTHETIC_ERRNO(EUCLEAN),
                                       "Core file has non-native endianness, not adjusting permissions.");
 
-        if (elf[EI_CLASS] == ELFCLASS64)
-                r = parse_auxv64(context->meta[META_PROC_AUXV],
-                                 context->meta_size[META_PROC_AUXV],
-                                 &at_secure, &uid, &euid, &gid, &egid);
-        else
-                r = parse_auxv32(context->meta[META_PROC_AUXV],
-                                 context->meta_size[META_PROC_AUXV],
-                                 &at_secure, &uid, &euid, &gid, &egid);
+        r = parse_auxv(LOG_WARNING,
+                       /* elf_class= */ elf[EI_CLASS],
+                       context->meta[META_PROC_AUXV],
+                       context->meta_size[META_PROC_AUXV],
+                       &at_secure, &uid, &euid, &gid, &egid);
         if (r < 0)
                 return r;
 
@@ -705,17 +642,16 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s
  * flags:  0100002
  * EOF
  */
-static int compose_open_fds(pid_t pid, char **open_fds) {
+static int compose_open_fds(pid_t pid, char **ret) {
+        _cleanup_(memstream_done) MemStream m = {};
         _cleanup_closedir_ DIR *proc_fd_dir = NULL;
         _cleanup_close_ int proc_fdinfo_fd = -EBADF;
-        _cleanup_free_ char *buffer = NULL;
-        _cleanup_fclose_ FILE *stream = NULL;
         const char *fddelim = "", *path;
-        size_t size = 0;
+        FILE *stream;
         int r;
 
         assert(pid >= 0);
-        assert(open_fds != NULL);
+        assert(ret);
 
         path = procfs_file_alloca(pid, "fd");
         proc_fd_dir = opendir(path);
@@ -726,7 +662,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
         if (proc_fdinfo_fd < 0)
                 return -errno;
 
-        stream = open_memstream_unlocked(&buffer, &size);
+        stream = memstream_init(&m);
         if (!stream)
                 return -ENOMEM;
 
@@ -765,15 +701,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
                 }
         }
 
-        errno = 0;
-        stream = safe_fclose(stream);
-
-        if (errno > 0)
-                return -errno;
-
-        *open_fds = TAKE_PTR(buffer);
-
-        return 0;
+        return memstream_finalize(&m, ret, NULL);
 }
 
 static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) {
@@ -1158,7 +1086,7 @@ static int process_socket(int fd) {
                         }
 
                         assert(input_fd < 0);
-                        input_fd = *(int*) CMSG_DATA(found);
+                        input_fd = *CMSG_TYPED_DATA(found, int);
                         break;
                 } else
                         cmsg_close_all(&mh);