]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
coredump: split out parse_auxv() to src/shared/
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 22 Mar 2023 08:53:16 +0000 (09:53 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 23 Mar 2023 17:04:22 +0000 (18:04 +0100)
No functional change. (We already checked for ELFCLASS32 or ELFCLASS64 before,
so even though there's a new check for other architectures, the only caller
only passes ELFCLASS32 or ELFCLASS64.)

src/coredump/coredump.c
src/shared/coredump-util.c
src/shared/coredump-util.h

index 1f259cf669bad995591de5514a9454fc6a242bbe..b7a62e72b0095775602d3cd1f58fd913fbf8e647 100644 (file)
@@ -49,7 +49,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 +335,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 +369,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;
 
index 3d2f1790492183ec20969eabcda1bb815b327370..bf8ea00b14cf00f72153d9859bc36f6465181cd6 100644 (file)
@@ -1,9 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <elf.h>
+
 #include "coredump-util.h"
 #include "extract-word.h"
 #include "fileio.h"
 #include "string-table.h"
+#include "unaligned.h"
 #include "virt.h"
 
 static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = {
@@ -65,6 +68,95 @@ int coredump_filter_mask_from_string(const char *s, uint64_t *ret) {
         return 0;
 }
 
+#define _DEFINE_PARSE_AUXV(size, type, unaligned_read)                  \
+        static int parse_auxv##size(                                    \
+                        int log_level,                                  \
+                        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);                        \
+                assert(at_secure);                                      \
+                assert(uid);                                            \
+                assert(euid);                                           \
+                assert(gid);                                            \
+                assert(egid);                                           \
+                                                                        \
+                if (size_bytes % (2 * sizeof(type)) != 0)               \
+                        return log_full_errno(log_level,                \
+                                              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_full_errno(log_level,                        \
+                                      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);
+
+int parse_auxv(int log_level,
+               uint8_t elf_class,
+               const void *auxv,
+               size_t size_bytes,
+               int *at_secure,
+               uid_t *uid,
+               uid_t *euid,
+               gid_t *gid,
+               gid_t *egid) {
+
+        switch (elf_class) {
+        case ELFCLASS64:
+                return parse_auxv64(log_level, auxv, size_bytes, at_secure, uid, euid, gid, egid);
+        case ELFCLASS32:
+                return parse_auxv32(log_level, auxv, size_bytes, at_secure, uid, euid, gid, egid);
+        default:
+                return log_full_errno(log_level, SYNTHETIC_ERRNO(EPROTONOSUPPORT),
+                                      "Unknown ELF class %d.", elf_class);
+        }
+}
+
 int set_coredump_filter(uint64_t value) {
         char t[STRLEN("0xFFFFFFFF")];
 
index 8eda86dfdb795432a90cb5852d33e6d7b084497d..99dbfde730ecd26eecad9974368a3f06a5c36dde 100644 (file)
@@ -26,5 +26,15 @@ const char* coredump_filter_to_string(CoredumpFilter i) _const_;
 CoredumpFilter coredump_filter_from_string(const char *s) _pure_;
 int coredump_filter_mask_from_string(const char *s, uint64_t *ret);
 
+int parse_auxv(int log_level,
+               uint8_t elf_class,
+               const void *auxv,
+               size_t size_bytes,
+               int *at_secure,
+               uid_t *uid,
+               uid_t *euid,
+               gid_t *gid,
+               gid_t *egid);
+
 int set_coredump_filter(uint64_t value);
 void disable_coredumps(void);