chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
journald: add additional simple static tests to verifier
[elogind.git]
/
src
/
journal
/
journal-verify.c
diff --git
a/src/journal/journal-verify.c
b/src/journal/journal-verify.c
index 598fc9beadf2f86c4f2c8acc317478685a9c28bc..7be0d2e5d76ef1b68f1236f28172a63c19a0dbbf 100644
(file)
--- a/
src/journal/journal-verify.c
+++ b/
src/journal/journal-verify.c
@@
-36,8
+36,6
@@
/* FIXME:
*
* - write bit mucking test
/* FIXME:
*
* - write bit mucking test
- * - tag timestamps should be between entry timestamps
- * - output validated time ranges
* - evolve key even if nothing happened in regular intervals
*
* - Allow building without libgcrypt
* - evolve key even if nothing happened in regular intervals
*
* - Allow building without libgcrypt
@@
-47,6
+45,8
@@
* */
static int journal_file_object_verify(JournalFile *f, Object *o) {
* */
static int journal_file_object_verify(JournalFile *f, Object *o) {
+ uint64_t i;
+
assert(f);
assert(o);
assert(f);
assert(o);
@@
-89,12
+89,22
@@
static int journal_file_object_verify(JournalFile *f, Object *o) {
if (h1 != h2)
return -EBADMSG;
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;
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:
break;
case OBJECT_ENTRY:
@@
-108,6
+118,12
@@
static int journal_file_object_verify(JournalFile *f, Object *o) {
le64toh(o->entry.realtime) <= 0)
return -EBADMSG;
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:
break;
case OBJECT_DATA_HASH_TABLE:
@@
-127,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 ((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:
break;
case OBJECT_TAG:
@@
-652,7
+671,10
@@
static int journal_file_parse_verification_key(JournalFile *f, const char *key)
return 0;
}
return 0;
}
-int journal_file_verify(JournalFile *f, const char *key) {
+int journal_file_verify(
+ JournalFile *f,
+ const char *key,
+ usec_t *first_validated, usec_t *last_validated, usec_t *last_contained) {
int r;
Object *o;
uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0;
int r;
Object *o;
uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0;
@@
-749,6
+771,12
@@
int journal_file_verify(JournalFile *f, const char *key) {
break;
case OBJECT_ENTRY:
break;
case OBJECT_ENTRY:
+ if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED) && n_tags <= 0) {
+ log_error("First entry before first tag at %llu", (unsigned long long) p);
+ r = -EBADMSG;
+ goto fail;
+ }
+
r = write_uint64(entry_fd, p);
if (r < 0)
goto fail;
r = write_uint64(entry_fd, p);
if (r < 0)
goto fail;
@@
-854,7
+882,7
@@
int journal_file_verify(JournalFile *f, const char *key) {
break;
case OBJECT_TAG: {
break;
case OBJECT_TAG: {
- uint64_t q;
+ uint64_t q
, rt
;
if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED)) {
log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED)) {
log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
@@
-876,8
+904,8
@@
int journal_file_verify(JournalFile *f, const char *key) {
goto fail;
}
goto fail;
}
-
last_tag_realtime
= (o->tag.epoch + 1) * f->fss_interval_usec + f->fss_start_usec;
- if (entry_realtime_set && entry_realtime >=
last_tag_realtime
) {
+
rt
= (o->tag.epoch + 1) * f->fss_interval_usec + f->fss_start_usec;
+ if (entry_realtime_set && entry_realtime >=
rt
) {
log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
@@
-929,6
+957,8
@@
int journal_file_verify(JournalFile *f, const char *key) {
f->hmac_running = false;
last_tag = p + ALIGN64(le64toh(o->object.size));
f->hmac_running = false;
last_tag = p + ALIGN64(le64toh(o->object.size));
+ last_tag_realtime = rt;
+
n_tags ++;
break;
}
n_tags ++;
break;
}
@@
-1056,6
+1086,13
@@
int journal_file_verify(JournalFile *f, const char *key) {
close_nointr_nofail(entry_fd);
close_nointr_nofail(entry_array_fd);
close_nointr_nofail(entry_fd);
close_nointr_nofail(entry_array_fd);
+ if (first_validated)
+ *first_validated = le64toh(f->header->head_entry_realtime);
+ if (last_validated)
+ *last_validated = last_tag_realtime;
+ if (last_contained)
+ *last_contained = le64toh(f->header->tail_entry_realtime);
+
return 0;
fail:
return 0;
fail: