From: Daan De Meyer Date: Mon, 29 Nov 2021 09:24:44 +0000 (+0100) Subject: journal: Add journal_file_read_object() X-Git-Tag: v250-rc1~59^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=117e21121e857b4b7d81949542e8dd257265970a;p=thirdparty%2Fsystemd.git journal: Add journal_file_read_object() --- diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 3722519dc42..7068b6bb178 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -990,6 +990,65 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset return 0; } +int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) { + int r; + Object o; + uint64_t s; + + assert(f); + assert(ret); + + /* Objects may only be located at multiple of 64 bit */ + if (!VALID64(offset)) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read object at non-64bit boundary: %" PRIu64, + offset); + + /* Object may not be located in the file header */ + if (offset < le64toh(f->header->header_size)) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read object located in file header: %" PRIu64, + offset); + + /* This will likely read too much data but it avoids having to call pread() twice. */ + r = pread(f->fd, &o, sizeof(Object), offset); + if (r < 0) + return r; + + s = le64toh(o.object.size); + + if (s == 0) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read uninitialized object: %" PRIu64, + offset); + if (s < sizeof(ObjectHeader)) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read overly short object: %" PRIu64, + offset); + + if (o.object.type <= OBJECT_UNUSED) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read object with invalid type: %" PRIu64, + offset); + + if (s < minimum_header_size(&o)) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read truncated object: %" PRIu64, + offset); + + if (type > OBJECT_UNUSED && o.object.type != type) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), + "Attempt to read object of unexpected type: %" PRIu64, + offset); + + r = journal_file_check_object(f, offset, &o); + if (r < 0) + return r; + + *ret = o; + return 0; +} + static uint64_t journal_file_entry_seqnum( JournalFile *f, uint64_t *seqnum) { diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h index 92784337c2e..81b2ff23e1d 100644 --- a/src/libsystemd/sd-journal/journal-file.h +++ b/src/libsystemd/sd-journal/journal-file.h @@ -202,6 +202,7 @@ static inline bool VALID_EPOCH(uint64_t u) { FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_KEYED_HASH) int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); +int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret); uint64_t journal_file_entry_n_items(Object *o) _pure_; uint64_t journal_file_entry_array_n_items(Object *o) _pure_;