]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/journal/journal-verify.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / journal / journal-verify.c
index f61f158e8a8c7a7cc226b59a254be3a55113e324..e756f51d0f260cad158caa4dea821a6881459382 100644 (file)
@@ -118,6 +118,11 @@ static void flush_progress(void) {
                 log_error(OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \
         } while (0)
 
+#define error_errno(_offset, error, _fmt, ...) do {               \
+                flush_progress();                                       \
+                log_error_errno(error, OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \
+        } while (0)
+
 static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) {
         uint64_t i;
 
@@ -145,7 +150,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         warning(offset, "Unused data (entry_offset==0)");
 
                 if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) {
-                        error(offset, "Bad n_entries: %"PRIu64, o->data.n_entries);
+                        error(offset, "Bad n_entries: %"PRIu64, le64toh(o->data.n_entries));
                         return -EBADMSG;
                 }
 
@@ -168,8 +173,8 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                                             le64toh(o->object.size) - offsetof(Object, data.payload),
                                             &b, &alloc, &b_size, 0);
                         if (r < 0) {
-                                error(offset, "%s decompression failed: %s",
-                                      object_compressed_to_string(compression), strerror(-r));
+                                error_errno(offset, r, "%s decompression failed: %m",
+                                            object_compressed_to_string(compression));
                                 return r;
                         }
 
@@ -182,15 +187,15 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         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)) {
+                if (!VALID64(le64toh(o->data.next_hash_offset)) ||
+                    !VALID64(le64toh(o->data.next_field_offset)) ||
+                    !VALID64(le64toh(o->data.entry_offset)) ||
+                    !VALID64(le64toh(o->data.entry_array_offset))) {
                         error(offset, "Invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
-                              o->data.next_hash_offset,
-                              o->data.next_field_offset,
-                              o->data.entry_offset,
-                              o->data.entry_array_offset);
+                              le64toh(o->data.next_hash_offset),
+                              le64toh(o->data.next_field_offset),
+                              le64toh(o->data.entry_offset),
+                              le64toh(o->data.entry_array_offset));
                         return -EBADMSG;
                 }
 
@@ -206,12 +211,12 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         return -EBADMSG;
                 }
 
-                if (!VALID64(o->field.next_hash_offset) ||
-                    !VALID64(o->field.head_data_offset)) {
+                if (!VALID64(le64toh(o->field.next_hash_offset)) ||
+                    !VALID64(le64toh(o->field.head_data_offset))) {
                         error(offset,
                               "Invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt,
-                              o->field.next_hash_offset,
-                              o->field.head_data_offset);
+                              le64toh(o->field.next_hash_offset),
+                              le64toh(o->field.head_data_offset));
                         return -EBADMSG;
                 }
                 break;
@@ -254,12 +259,12 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                 }
 
                 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)) {
+                        if (le64toh(o->entry.items[i].object_offset) == 0 ||
+                            !VALID64(le64toh(o->entry.items[i].object_offset))) {
                                 error(offset,
                                       "Invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt,
                                       i, journal_file_entry_n_items(o),
-                                      o->entry.items[i].object_offset);
+                                      le64toh(o->entry.items[i].object_offset));
                                 return -EBADMSG;
                         }
                 }
@@ -320,10 +325,10 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         return -EBADMSG;
                 }
 
-                if (!VALID64(o->entry_array.next_entry_array_offset)) {
+                if (!VALID64(le64toh(o->entry_array.next_entry_array_offset))) {
                         error(offset,
                               "Invalid object entry array next_entry_array_offset: "OFSfmt,
-                              o->entry_array.next_entry_array_offset);
+                              le64toh(o->entry_array.next_entry_array_offset));
                         return -EBADMSG;
                 }
 
@@ -347,10 +352,10 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                         return -EBADMSG;
                 }
 
-                if (!VALID_EPOCH(o->tag.epoch)) {
+                if (!VALID_EPOCH(le64toh(o->tag.epoch))) {
                         error(offset,
                               "Invalid object tag epoch: %"PRIu64,
-                              o->tag.epoch);
+                              le64toh(o->tag.epoch));
                         return -EBADMSG;
                 }
 
@@ -372,12 +377,12 @@ static int write_uint64(int fd, uint64_t p) {
         return 0;
 }
 
-static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
+static int contains_uint64(MMapCache *m, MMapFileDescriptor *f, uint64_t n, uint64_t p) {
         uint64_t a, b;
         int r;
 
         assert(m);
-        assert(fd >= 0);
+        assert(f);
 
         /* Bisection ... */
 
@@ -387,7 +392,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
 
                 c = (a + b) / 2;
 
-                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
+                r = mmap_cache_get(m, f, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z, NULL);
                 if (r < 0)
                         return r;
 
@@ -408,7 +413,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
 
 static int entry_points_to_data(
                 JournalFile *f,
-                int entry_fd,
+                MMapFileDescriptor *cache_entry_fd,
                 uint64_t n_entries,
                 uint64_t entry_p,
                 uint64_t data_p) {
@@ -419,9 +424,9 @@ static int entry_points_to_data(
         bool found = false;
 
         assert(f);
-        assert(entry_fd >= 0);
+        assert(cache_entry_fd);
 
-        if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
+        if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, entry_p)) {
                 error(data_p, "Data object references invalid entry at "OFSfmt, entry_p);
                 return -EBADMSG;
         }
@@ -495,16 +500,16 @@ static int entry_points_to_data(
 static int verify_data(
                 JournalFile *f,
                 Object *o, uint64_t p,
-                int entry_fd, uint64_t n_entries,
-                int entry_array_fd, uint64_t n_entry_arrays) {
+                MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+                MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays) {
 
         uint64_t i, n, a, last, q;
         int r;
 
         assert(f);
         assert(o);
-        assert(entry_fd >= 0);
-        assert(entry_array_fd >= 0);
+        assert(cache_entry_fd);
+        assert(cache_entry_array_fd);
 
         n = le64toh(o->data.n_entries);
         a = le64toh(o->data.entry_array_offset);
@@ -522,7 +527,7 @@ static int verify_data(
         assert(o->data.entry_offset);
 
         last = q = le64toh(o->data.entry_offset);
-        r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+        r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
         if (r < 0)
                 return r;
 
@@ -535,7 +540,7 @@ static int verify_data(
                         return -EBADMSG;
                 }
 
-                if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+                if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
                         error(p, "Invalid array offset "OFSfmt, a);
                         return -EBADMSG;
                 }
@@ -560,7 +565,7 @@ static int verify_data(
                         }
                         last = q;
 
-                        r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+                        r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
                         if (r < 0)
                                 return r;
 
@@ -578,9 +583,9 @@ static int verify_data(
 
 static int verify_hash_table(
                 JournalFile *f,
-                int data_fd, uint64_t n_data,
-                int entry_fd, uint64_t n_entries,
-                int entry_array_fd, uint64_t n_entry_arrays,
+                MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+                MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+                MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
                 usec_t *last_usec,
                 bool show_progress) {
 
@@ -588,9 +593,9 @@ static int verify_hash_table(
         int r;
 
         assert(f);
-        assert(data_fd >= 0);
-        assert(entry_fd >= 0);
-        assert(entry_array_fd >= 0);
+        assert(cache_data_fd);
+        assert(cache_entry_fd);
+        assert(cache_entry_array_fd);
         assert(last_usec);
 
         n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
@@ -612,7 +617,7 @@ static int verify_hash_table(
                         Object *o;
                         uint64_t next;
 
-                        if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
+                        if (!contains_uint64(f->mmap, cache_data_fd, n_data, p)) {
                                 error(p, "Invalid data object at hash entry %"PRIu64" of %"PRIu64, i, n);
                                 return -EBADMSG;
                         }
@@ -632,7 +637,7 @@ static int verify_hash_table(
                                 return -EBADMSG;
                         }
 
-                        r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
+                        r = verify_data(f, o, p, cache_entry_fd, n_entries, cache_entry_array_fd, n_entry_arrays);
                         if (r < 0)
                                 return r;
 
@@ -684,14 +689,14 @@ static int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p)
 static int verify_entry(
                 JournalFile *f,
                 Object *o, uint64_t p,
-                int data_fd, uint64_t n_data) {
+                MMapFileDescriptor *cache_data_fd, uint64_t n_data) {
 
         uint64_t i, n;
         int r;
 
         assert(f);
         assert(o);
-        assert(data_fd >= 0);
+        assert(cache_data_fd);
 
         n = journal_file_entry_n_items(o);
         for (i = 0; i < n; i++) {
@@ -701,7 +706,7 @@ static int verify_entry(
                 q = le64toh(o->entry.items[i].object_offset);
                 h = le64toh(o->entry.items[i].hash);
 
-                if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
+                if (!contains_uint64(f->mmap, cache_data_fd, n_data, q)) {
                         error(p, "Invalid data object of entry");
                         return -EBADMSG;
                 }
@@ -729,9 +734,9 @@ static int verify_entry(
 
 static int verify_entry_array(
                 JournalFile *f,
-                int data_fd, uint64_t n_data,
-                int entry_fd, uint64_t n_entries,
-                int entry_array_fd, uint64_t n_entry_arrays,
+                MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+                MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+                MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
                 usec_t *last_usec,
                 bool show_progress) {
 
@@ -739,9 +744,9 @@ static int verify_entry_array(
         int r;
 
         assert(f);
-        assert(data_fd >= 0);
-        assert(entry_fd >= 0);
-        assert(entry_array_fd >= 0);
+        assert(cache_data_fd);
+        assert(cache_entry_fd);
+        assert(cache_entry_array_fd);
         assert(last_usec);
 
         n = le64toh(f->header->n_entries);
@@ -758,7 +763,7 @@ static int verify_entry_array(
                         return -EBADMSG;
                 }
 
-                if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+                if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
                         error(a, "Invalid array %"PRIu64" of %"PRIu64, i, n);
                         return -EBADMSG;
                 }
@@ -784,7 +789,7 @@ static int verify_entry_array(
                         }
                         last = p;
 
-                        if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
+                        if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, p)) {
                                 error(a, "Invalid array entry at %"PRIu64" of %"PRIu64, i, n);
                                 return -EBADMSG;
                         }
@@ -793,7 +798,7 @@ static int verify_entry_array(
                         if (r < 0)
                                 return r;
 
-                        r = verify_entry(f, o, p, data_fd, n_data);
+                        r = verify_entry(f, o, p, cache_data_fd, n_data);
                         if (r < 0)
                                 return r;
 
@@ -824,17 +829,18 @@ int journal_file_verify(
         uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0, n_tags = 0;
         usec_t last_usec = 0;
         int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
+        MMapFileDescriptor *cache_data_fd = NULL, *cache_entry_fd = NULL, *cache_entry_array_fd = NULL;
         unsigned i;
         bool found_last = false;
-        _cleanup_free_ char *tmp_dir = NULL;
+        const char *tmp_dir = NULL;
 
-#ifdef HAVE_GCRYPT
+#if HAVE_GCRYPT
         uint64_t last_tag = 0;
 #endif
         assert(f);
 
         if (key) {
-#ifdef HAVE_GCRYPT
+#if HAVE_GCRYPT
                 r = journal_file_parse_verification_key(f, key);
                 if (r < 0) {
                         log_error("Failed to parse seed.");
@@ -846,7 +852,7 @@ int journal_file_verify(
         } else if (f->seal)
                 return -ENOKEY;
 
-        r = var_tmp(&tmp_dir);
+        r = var_tmp_dir(&tmp_dir);
         if (r < 0) {
                 log_error_errno(r, "Failed to determine temporary directory: %m");
                 goto fail;
@@ -871,6 +877,24 @@ int journal_file_verify(
                 goto fail;
         }
 
+        cache_data_fd = mmap_cache_add_fd(f->mmap, data_fd);
+        if (!cache_data_fd) {
+                r = log_oom();
+                goto fail;
+        }
+
+        cache_entry_fd = mmap_cache_add_fd(f->mmap, entry_fd);
+        if (!cache_entry_fd) {
+                r = log_oom();
+                goto fail;
+        }
+
+        cache_entry_array_fd = mmap_cache_add_fd(f->mmap, entry_array_fd);
+        if (!cache_entry_array_fd) {
+                r = log_oom();
+                goto fail;
+        }
+
         if (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SUPPORTED) {
                 log_error("Cannot verify file with unknown extensions.");
                 r = -EOPNOTSUPP;
@@ -912,7 +936,7 @@ int journal_file_verify(
 
                 r = journal_file_object_verify(f, p, o);
                 if (r < 0) {
-                        error(p, "Invalid object contents: %s", strerror(-r));
+                        error_errno(p, r, "Invalid object contents: %m");
                         goto fail;
                 }
 
@@ -1079,13 +1103,13 @@ int journal_file_verify(
                                 goto fail;
                         }
 
-#ifdef HAVE_GCRYPT
+#if HAVE_GCRYPT
                         if (f->seal) {
                                 uint64_t q, rt;
 
                                 debug(p, "Checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
 
-                                rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
+                                rt = f->fss_start_usec + le64toh(o->tag.epoch) * f->fss_interval_usec;
                                 if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
                                         error(p, "tag/entry realtime timestamp out of synchronization");
                                         r = -EBADMSG;
@@ -1242,18 +1266,18 @@ int journal_file_verify(
          * referenced is consistent. */
 
         r = verify_entry_array(f,
-                               data_fd, n_data,
-                               entry_fd, n_entries,
-                               entry_array_fd, n_entry_arrays,
+                               cache_data_fd, n_data,
+                               cache_entry_fd, n_entries,
+                               cache_entry_array_fd, n_entry_arrays,
                                &last_usec,
                                show_progress);
         if (r < 0)
                 goto fail;
 
         r = verify_hash_table(f,
-                              data_fd, n_data,
-                              entry_fd, n_entries,
-                              entry_array_fd, n_entry_arrays,
+                              cache_data_fd, n_data,
+                              cache_entry_fd, n_entries,
+                              cache_entry_array_fd, n_entry_arrays,
                               &last_usec,
                               show_progress);
         if (r < 0)
@@ -1262,9 +1286,9 @@ int journal_file_verify(
         if (show_progress)
                 flush_progress();
 
-        mmap_cache_close_fd(f->mmap, data_fd);
-        mmap_cache_close_fd(f->mmap, entry_fd);
-        mmap_cache_close_fd(f->mmap, entry_array_fd);
+        mmap_cache_free_fd(f->mmap, cache_data_fd);
+        mmap_cache_free_fd(f->mmap, cache_entry_fd);
+        mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
 
         safe_close(data_fd);
         safe_close(entry_fd);
@@ -1289,20 +1313,23 @@ fail:
                   (unsigned long long) f->last_stat.st_size,
                   100 * p / f->last_stat.st_size);
 
-        if (data_fd >= 0) {
-                mmap_cache_close_fd(f->mmap, data_fd);
+        if (data_fd >= 0)
                 safe_close(data_fd);
-        }
 
-        if (entry_fd >= 0) {
-                mmap_cache_close_fd(f->mmap, entry_fd);
+        if (entry_fd >= 0)
                 safe_close(entry_fd);
-        }
 
-        if (entry_array_fd >= 0) {
-                mmap_cache_close_fd(f->mmap, entry_array_fd);
+        if (entry_array_fd >= 0)
                 safe_close(entry_array_fd);
-        }
+
+        if (cache_data_fd)
+                mmap_cache_free_fd(f->mmap, cache_data_fd);
+
+        if (cache_entry_fd)
+                mmap_cache_free_fd(f->mmap, cache_entry_fd);
+
+        if (cache_entry_array_fd)
+                mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
 
         return r;
 }