X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournal-verify.c;h=8ef91ce4854fdb337c256af2771aec0421f6b5f8;hp=f3182e876ea1bfef14bd732626cce9d2b25966e8;hb=fd5dc3204d350142a9105d3e9c83bf29d3a900ee;hpb=0284adc6a60ce0af1107cb0b50041a65d731f39e diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index f3182e876..8ef91ce48 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -29,6 +29,17 @@ #include "journal-file.h" #include "journal-authenticate.h" #include "journal-verify.h" +#include "lookup3.h" +#include "compress.h" + +/* FIXME: + * + * - follow all chains + * - check for unreferenced objects + * - verify FSPRG + * - Allow building without libgcrypt + * + * */ static int journal_file_object_verify(JournalFile *f, Object *o) { assert(f); @@ -38,15 +49,43 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { * possible field values. It does not follow any references to * other objects. */ + if ((o->object.flags & OBJECT_COMPRESSED) && + o->object.type != OBJECT_DATA) + return -EBADMSG; + switch (o->object.type) { - case OBJECT_DATA: + + case OBJECT_DATA: { + uint64_t h1, h2; + if (le64toh(o->data.entry_offset) <= 0 || le64toh(o->data.n_entries) <= 0) return -EBADMSG; if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) return -EBADMSG; + + h1 = le64toh(o->data.hash); + + if (o->object.flags & OBJECT_COMPRESSED) { + void *b = NULL; + uint64_t alloc = 0, b_size; + + if (!uncompress_blob(o->data.payload, + le64toh(o->object.size) - offsetof(Object, data.payload), + &b, &alloc, &b_size)) + return -EBADMSG; + + h2 = hash64(b, b_size); + free(b); + } else + h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); + + if (h1 != h2) + return -EBADMSG; + break; + } case OBJECT_FIELD: if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) @@ -251,12 +290,6 @@ int journal_file_verify(JournalFile *f, const char *key) { goto fail; } - r = journal_file_hmac_put_object(f, -1, p); - if (r < 0) { - log_error("Failed to calculate HMAC at %llu", (unsigned long long) p); - goto fail; - } - if (o->object.flags & OBJECT_COMPRESSED && !(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED)) { log_error("Compressed object without compression at %llu", (unsigned long long) p); @@ -264,10 +297,9 @@ int journal_file_verify(JournalFile *f, const char *key) { goto fail; } - if (o->object.flags & OBJECT_COMPRESSED && - o->object.type != OBJECT_DATA) { - log_error("Compressed non-data object at %llu", (unsigned long long) p); - r = -EBADMSG; + r = journal_file_hmac_put_object(f, -1, p); + if (r < 0) { + log_error("Failed to calculate HMAC at %llu", (unsigned long long) p); goto fail; }