journald: add additional simple static tests to verifier
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user