X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournal-verify.c;h=5a0751f2aa09f40f715478ab0c748fd7ebddfbc7;hb=3f2650377631aed3bc26fdbc3a2eef6e33cdf7e7;hp=82b0f0a98bb23a7ffa0bdc657819eabc78f09eb5;hpb=af13a6b0606f166c93cafc9892343f167f880281;p=elogind.git diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 82b0f0a98..5a0751f2a 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -34,10 +34,6 @@ #include "compress.h" #include "fsprg.h" -/* Use six characters to cover the offsets common in smallish journal - * files without adding to many zeros. */ -#define OFSfmt "%06"PRIx64 - static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) { uint64_t i; @@ -49,7 +45,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o * possible field values. It does not follow any references to * other objects. */ - if ((o->object.flags & OBJECT_COMPRESSED) && + if ((o->object.flags & OBJECT_COMPRESSED_XZ) && o->object.type != OBJECT_DATA) return -EBADMSG; @@ -57,6 +53,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o case OBJECT_DATA: { uint64_t h1, h2; + int compression, r; if (le64toh(o->data.entry_offset) == 0) log_warning(OFSfmt": unused data (entry_offset==0)", offset); @@ -76,24 +73,22 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o h1 = le64toh(o->data.hash); - if (o->object.flags & OBJECT_COMPRESSED) { -#ifdef HAVE_XZ - void *b = NULL; + compression = o->object.flags & OBJECT_COMPRESSION_MASK; + if (compression) { + _cleanup_free_ void *b = NULL; uint64_t alloc = 0, b_size; - if (!uncompress_blob(o->data.payload, - le64toh(o->object.size) - offsetof(Object, data.payload), - &b, &alloc, &b_size, 0)) { - log_error(OFSfmt": uncompression failed", offset); - return -EBADMSG; + r = decompress_blob(compression, + o->data.payload, + le64toh(o->object.size) - offsetof(Object, data.payload), + &b, &alloc, &b_size, 0); + if (r < 0) { + log_error(OFSfmt": %s decompression failed: %s", offset, + object_compressed_to_string(compression), strerror(-r)); + return r; } h2 = hash64(b, b_size); - free(b); -#else - log_error("Compression is not supported"); - return -EPROTONOSUPPORT; -#endif } else h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); @@ -789,9 +784,6 @@ 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; - char data_path[] = "/var/tmp/journal-data-XXXXXX", - entry_path[] = "/var/tmp/journal-entry-XXXXXX", - entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX"; unsigned i; bool found_last; #ifdef HAVE_GCRYPT @@ -812,29 +804,26 @@ int journal_file_verify( } else if (f->seal) return -ENOKEY; - data_fd = mkostemp(data_path, O_CLOEXEC); + data_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC); if (data_fd < 0) { log_error("Failed to create data file: %m"); r = -errno; goto fail; } - unlink(data_path); - entry_fd = mkostemp(entry_path, O_CLOEXEC); + entry_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC); if (entry_fd < 0) { log_error("Failed to create entry file: %m"); r = -errno; goto fail; } - unlink(entry_path); - entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC); + entry_array_fd = open_tmpfile("/var/tmp", O_RDWR | O_CLOEXEC); if (entry_array_fd < 0) { log_error("Failed to create entry array file: %m"); r = -errno; goto fail; } - unlink(entry_array_path); #ifdef HAVE_GCRYPT if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0) @@ -885,8 +874,21 @@ int journal_file_verify( goto fail; } - if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) { - log_error("Compressed object in file without compression at "OFSfmt, p); + if ((o->object.flags & OBJECT_COMPRESSED_XZ) && + (o->object.flags & OBJECT_COMPRESSED_LZ4)) { + log_error("Objected with double compression at "OFSfmt, p); + r = -EBADMSG; + goto fail; + } + + if ((o->object.flags & OBJECT_COMPRESSED_XZ) && !JOURNAL_HEADER_COMPRESSED_XZ(f->header)) { + log_error("XZ compressed object in file without XZ compression at "OFSfmt, p); + r = -EBADMSG; + goto fail; + } + + if ((o->object.flags & OBJECT_COMPRESSED_LZ4) && !JOURNAL_HEADER_COMPRESSED_LZ4(f->header)) { + log_error("LZ4 compressed object in file without LZ4 compression at "OFSfmt, p); r = -EBADMSG; goto fail; } @@ -1232,9 +1234,9 @@ int journal_file_verify( mmap_cache_close_fd(f->mmap, entry_fd); mmap_cache_close_fd(f->mmap, entry_array_fd); - close_nointr_nofail(data_fd); - close_nointr_nofail(entry_fd); - close_nointr_nofail(entry_array_fd); + safe_close(data_fd); + safe_close(entry_fd); + safe_close(entry_array_fd); if (first_contained) *first_contained = le64toh(f->header->head_entry_realtime); @@ -1257,17 +1259,17 @@ fail: if (data_fd >= 0) { mmap_cache_close_fd(f->mmap, data_fd); - close_nointr_nofail(data_fd); + safe_close(data_fd); } if (entry_fd >= 0) { mmap_cache_close_fd(f->mmap, entry_fd); - close_nointr_nofail(entry_fd); + safe_close(entry_fd); } if (entry_array_fd >= 0) { mmap_cache_close_fd(f->mmap, entry_array_fd); - close_nointr_nofail(entry_array_fd); + safe_close(entry_array_fd); } return r;