X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournal-file.c;h=f775fec444004b27e6d053aff08f2ee487fb45a2;hb=be3ea5eaf24f4507efe88b450f751da860a9d21c;hp=697e7f3606896add66c83255386667d80ad84716;hpb=2b43f939a4b3ad5aeb2650868b0234ff42ec0045;p=elogind.git diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 697e7f360..f775fec44 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -221,10 +221,16 @@ static int journal_file_verify_header(JournalFile *f) { 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)) + if (!VALID64(le64toh(f->header->data_hash_table_offset)) || + !VALID64(le64toh(f->header->field_hash_table_offset)) || + !VALID64(le64toh(f->header->tail_object_offset)) || + !VALID64(le64toh(f->header->entry_array_offset))) + return -ENODATA; + + if (le64toh(f->header->data_hash_table_offset) < le64toh(f->header->header_size) || + le64toh(f->header->field_hash_table_offset) < le64toh(f->header->header_size) || + le64toh(f->header->tail_object_offset) < le64toh(f->header->header_size) || + le64toh(f->header->entry_array_offset) < le64toh(f->header->header_size)) return -ENODATA; if (f->writable) { @@ -254,8 +260,7 @@ static int journal_file_verify_header(JournalFile *f) { f->compress = JOURNAL_HEADER_COMPRESSED(f->header); - if (f->writable) - f->seal = JOURNAL_HEADER_SEALED(f->header); + f->seal = JOURNAL_HEADER_SEALED(f->header); return 0; } @@ -323,6 +328,9 @@ static int journal_file_move_to(JournalFile *f, int context, bool keep_always, u assert(f); assert(ret); + if (size <= 0) + return -EINVAL; + /* Avoid SIGBUS on invalid accesses */ if (offset + size > (uint64_t) f->last_stat.st_size) { /* Hmm, out of range? Let's refresh the fstat() data @@ -581,7 +589,9 @@ static int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, ui assert(f); assert(o); assert(offset > 0); - assert(o->object.type == OBJECT_DATA); + + if (o->object.type != OBJECT_DATA) + return -EINVAL; /* This might alter the window we are looking at */ @@ -766,18 +776,18 @@ static int journal_file_append_data( if (r < 0) return r; -#ifdef HAVE_GCRYPT - r = journal_file_hmac_put_object(f, OBJECT_DATA, p); - if (r < 0) - return r; -#endif - /* The linking might have altered the window, so let's * refresh our pointer */ r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); if (r < 0) return r; +#ifdef HAVE_GCRYPT + r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p); + if (r < 0) + return r; +#endif + if (ret) *ret = o; @@ -789,22 +799,28 @@ static int journal_file_append_data( uint64_t journal_file_entry_n_items(Object *o) { assert(o); - assert(o->object.type == OBJECT_ENTRY); + + if (o->object.type != OBJECT_ENTRY) + return 0; return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem); } uint64_t journal_file_entry_array_n_items(Object *o) { assert(o); - assert(o->object.type == OBJECT_ENTRY_ARRAY); + + if (o->object.type != OBJECT_ENTRY_ARRAY) + return 0; return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t); } uint64_t journal_file_hash_table_n_items(Object *o) { assert(o); - assert(o->object.type == OBJECT_DATA_HASH_TABLE || - o->object.type == OBJECT_FIELD_HASH_TABLE); + + if (o->object.type != OBJECT_DATA_HASH_TABLE && + o->object.type != OBJECT_FIELD_HASH_TABLE) + return 0; return (le64toh(o->object.size) - offsetof(Object, hash_table.items)) / sizeof(HashItem); } @@ -857,7 +873,7 @@ static int link_entry_into_array(JournalFile *f, return r; #ifdef HAVE_GCRYPT - r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, q); + r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, o, q); if (r < 0) return r; #endif @@ -940,7 +956,9 @@ static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) { assert(f); assert(o); assert(offset > 0); - assert(o->object.type == OBJECT_ENTRY); + + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; __sync_synchronize(); @@ -1003,7 +1021,7 @@ static int journal_file_append_entry_internal( o->entry.boot_id = f->header->boot_id; #ifdef HAVE_GCRYPT - r = journal_file_hmac_put_object(f, OBJECT_ENTRY, np); + r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np); if (r < 0) return r; #endif @@ -1032,7 +1050,7 @@ void journal_file_post_change(JournalFile *f) { __sync_synchronize(); if (ftruncate(f->fd, f->last_stat.st_size) < 0) - log_error("Failed to to truncate file to its own size: %m"); + log_error("Failed to truncate file to its own size: %m"); } int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) { @@ -1906,6 +1924,8 @@ fail: void journal_file_print_header(JournalFile *f) { char a[33], b[33], c[33]; char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX]; + struct stat st; + char bytes[FORMAT_BYTES_MAX]; assert(f); @@ -1970,6 +1990,9 @@ void journal_file_print_header(JournalFile *f) { if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) printf("Entry Array Objects: %llu\n", (unsigned long long) le64toh(f->header->n_entry_arrays)); + + if (fstat(f->fd, &st) >= 0) + printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL)); } int journal_file_open( @@ -1988,6 +2011,7 @@ int journal_file_open( bool newly_created = false; assert(fname); + assert(ret); if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR) @@ -2007,8 +2031,12 @@ int journal_file_open( f->flags = flags; f->prot = prot_from_flags(flags); f->writable = (flags & O_ACCMODE) != O_RDONLY; +#ifdef HAVE_XZ f->compress = compress; +#endif +#ifdef HAVE_GCRYPT f->seal = seal; +#endif if (mmap_cache) f->mmap = mmap_cache_ref(mmap_cache); @@ -2043,9 +2071,11 @@ int journal_file_open( #ifdef HAVE_GCRYPT /* Try to load the FSPRG state, and if we can't, then * just don't do sealing */ - r = journal_file_fss_load(f); - if (r < 0) - f->seal = false; + if (f->seal) { + r = journal_file_fss_load(f); + if (r < 0) + f->seal = false; + } #endif r = journal_file_init_header(f, template); @@ -2126,9 +2156,7 @@ int journal_file_open( if (r < 0) goto fail; - if (ret) - *ret = f; - + *ret = f; return 0; fail: