From: Lennart Poettering Date: Fri, 17 Aug 2012 22:37:21 +0000 (+0200) Subject: journald: add additional simple static tests to verifier X-Git-Tag: v189~48 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=db11ac1ab56bc13514a029e7d126c5efe2c68bc2 journald: add additional simple static tests to verifier --- diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h index 52c55ab4b..45c3cde9f 100644 --- a/src/journal/journal-def.h +++ b/src/journal/journal-def.h @@ -140,9 +140,10 @@ union Object { }; enum { - STATE_OFFLINE, - STATE_ONLINE, - STATE_ARCHIVED + STATE_OFFLINE = 0, + STATE_ONLINE = 1, + STATE_ARCHIVED = 2, + _STATE_MAX }; /* Header flags */ diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 08d4285d0..3cf28a7f3 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -203,6 +203,9 @@ static int journal_file_verify_header(JournalFile *f) { #endif } + if (f->header->state >= _STATE_MAX) + return -EBADMSG; + /* The first addition was n_data, so check that we are at least this large */ if (le64toh(f->header->header_size) < HEADER_SIZE_MIN) return -EBADMSG; @@ -211,7 +214,16 @@ static int journal_file_verify_header(JournalFile *f) { !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) return -EBADMSG; - if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->header_size) + le64toh(f->header->arena_size))) + if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size) + return -ENODATA; + + if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size))) + return -ENODATA; + + if (!VALID64(f->header->data_hash_table_offset) || + !VALID64(f->header->field_hash_table_offset) || + !VALID64(f->header->tail_object_offset) || + !VALID64(f->header->entry_array_offset)) return -ENODATA; if (f->writable) { @@ -351,6 +363,10 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec assert(f); assert(ret); + /* Objects may only be located at multiple of 64 bit */ + if (!VALID64(offset)) + return -EFAULT; + /* One context for each type, plus one catch-all for the rest */ context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0; diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index 58de21435..2d2bf319a 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -117,6 +117,7 @@ int journal_file_open_reliably( JournalFile **ret); #define ALIGN64(x) (((x) + 7ULL) & ~7ULL) +#define VALID64(x) (((x) & 7ULL) == 0ULL) #define JOURNAL_HEADER_CONTAINS(h, field) \ (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index f9a930e42..7be0d2e5d 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -45,6 +45,8 @@ * */ static int journal_file_object_verify(JournalFile *f, Object *o) { + uint64_t i; + assert(f); assert(o); @@ -87,12 +89,22 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { if (h1 != h2) return -EBADMSG; + if (!VALID64(o->data.next_hash_offset) || + !VALID64(o->data.next_field_offset) || + !VALID64(o->data.entry_offset) || + !VALID64(o->data.entry_array_offset)) + return -EBADMSG; + break; } case OBJECT_FIELD: if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) return -EBADMSG; + + if (!VALID64(o->field.next_hash_offset) || + !VALID64(o->field.head_data_offset)) + return -EBADMSG; break; case OBJECT_ENTRY: @@ -106,6 +118,12 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { le64toh(o->entry.realtime) <= 0) return -EBADMSG; + for (i = 0; i < journal_file_entry_n_items(o); i++) { + if (o->entry.items[i].object_offset == 0 || + !VALID64(o->entry.items[i].object_offset)) + return -EBADMSG; + } + break; case OBJECT_DATA_HASH_TABLE: @@ -125,6 +143,9 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) return -EBADMSG; + if (!VALID64(o->entry_array.next_entry_array_offset)) + return -EBADMSG; + break; case OBJECT_TAG: