X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournal-verify.c;h=6871433402e394fb3998f250d9014fe8def2a147;hb=56e81f7ca8276e40f8c88c4c30713a5b54009613;hp=7c99d44838b3608c8f80176dd65a050932cf104d;hpb=86adf873be22a38dbc9c6e86124c30b6caecd185;p=elogind.git diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 7c99d4483..687143340 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -31,6 +31,7 @@ #include "journal-verify.h" #include "lookup3.h" #include "compress.h" +#include "fsprg.h" /* FIXME: * @@ -38,7 +39,6 @@ * - Allow building without libgcrypt * - check with sparse * - 64bit conversions - * - verification should use MAP_PRIVATE * * */ @@ -316,6 +316,7 @@ static int verify_data( if (r < 0) return r; + i = 1; while (i < n) { uint64_t next, m, j; @@ -591,7 +592,62 @@ static int verify_entry_array( return 0; } -int journal_file_verify(JournalFile *f, const char *key) { +static int journal_file_parse_seed(JournalFile *f, const char *s) { + uint8_t *seed; + size_t seed_size, c; + const char *k; + int r; + unsigned long long start, interval; + + seed_size = FSPRG_RECOMMENDED_SEEDLEN; + seed = malloc(seed_size); + if (!seed) + return -ENOMEM; + + k = s; + for (c = 0; c < seed_size; c++) { + int x, y; + + while (*k == '-') + k++; + + x = unhexchar(*k); + if (x < 0) { + free(seed); + return -EINVAL; + } + k++; + y = unhexchar(*k); + if (y < 0) { + free(seed); + return -EINVAL; + } + k++; + + seed[c] = (uint8_t) (x * 16 + y); + } + + if (*k != '/') { + free(seed); + return -EINVAL; + } + k++; + + r = sscanf(k, "%llx-%llx", &start, &interval); + if (r != 2) { + free(seed); + return -EINVAL; + } + + f->fsprg_seed = seed; + f->fsprg_seed_size = seed_size; + f->fsprg_start_usec = start; + f->fsprg_interval_usec = interval; + + return 0; +} + +int journal_file_verify(JournalFile *f, const char *seed) { int r; Object *o; uint64_t p = 0; @@ -607,9 +663,18 @@ int journal_file_verify(JournalFile *f, const char *key) { assert(f); + if (seed) { + r = journal_file_parse_seed(f, seed); + if (r < 0) { + log_error("Failed to parse seed."); + return r; + } + } + data_fd = mkostemp(data_path, O_CLOEXEC); if (data_fd < 0) { log_error("Failed to create data file: %m"); + r = -errno; goto fail; } unlink(data_path); @@ -617,6 +682,7 @@ int journal_file_verify(JournalFile *f, const char *key) { entry_fd = mkostemp(entry_path, O_CLOEXEC); if (entry_fd < 0) { log_error("Failed to create entry file: %m"); + r = -errno; goto fail; } unlink(entry_path); @@ -624,6 +690,7 @@ int journal_file_verify(JournalFile *f, const char *key) { entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC); if (entry_array_fd < 0) { log_error("Failed to create entry array file: %m"); + r = -errno; goto fail; } unlink(entry_array_path); @@ -834,6 +901,13 @@ int journal_file_verify(JournalFile *f, const char *key) { goto fail; } + if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) && + n_entry_arrays != le64toh(f->header->n_entry_arrays)) { + log_error("Entry array number mismatch"); + r = -EBADMSG; + goto fail; + } + if (n_data_hash_tables != 1) { log_error("Missing data hash table"); r = -EBADMSG;