journald: add additional simple static tests to verifier
authorLennart Poettering <lennart@poettering.net>
Fri, 17 Aug 2012 22:37:21 +0000 (00:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 17 Aug 2012 22:37:21 +0000 (00:37 +0200)
src/journal/journal-def.h
src/journal/journal-file.c
src/journal/journal-file.h
src/journal/journal-verify.c

index 52c55ab..45c3cde 100644 (file)
@@ -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 */
index 08d4285..3cf28a7 100644 (file)
@@ -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;
 
index 58de214..2d2bf31 100644 (file)
@@ -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))
index f9a930e..7be0d2e 100644 (file)
@@ -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: