diff --git a/src/basic/iovec-util.c b/src/basic/iovec-util.c index 429f08dea9..0be326a183 100644 --- a/src/basic/iovec-util.c +++ b/src/basic/iovec-util.c @@ -16,6 +16,17 @@ const struct iovec iovec_empty = { .iov_len = 0, }; +int iovec_alloc(size_t n, struct iovec *ret) { + assert(ret); + + void *buf = malloc(n ?: 1); + if (!buf) + return -ENOMEM; + + *ret = IOVEC_MAKE(buf, n); + return 0; +} + size_t iovec_total_size(const struct iovec *iovec, size_t n) { size_t sum = 0; @@ -63,6 +74,15 @@ struct iovec* iovec_make_string(struct iovec *iovec, const char *s) { return iovec; } +void iovec_erase(struct iovec *iovec) { + assert(iovec); + + /* Unlike iovec_done_erase(), which derives the buffer size with MALLOC_SIZEOF_SAFE(), this uses + * iov_len as the buffer size. Hence, it can be used with iovec referring to a static array or a + * buffer allocated on the stack. */ + explicit_bzero_safe(iovec->iov_base, iovec->iov_len); +} + void iovec_done_erase(struct iovec *iovec) { assert(iovec); diff --git a/src/basic/iovec-util.h b/src/basic/iovec-util.h index 35cdce6a76..ade2e6be34 100644 --- a/src/basic/iovec-util.h +++ b/src/basic/iovec-util.h @@ -10,6 +10,8 @@ extern const struct iovec iovec_nul_byte; /* Points to a single NUL byte */ extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e. non-NULL) pointer */ +int iovec_alloc(size_t n, struct iovec *ret); + size_t iovec_total_size(const struct iovec *iovec, size_t n) _nonnull_if_nonzero_(1, 2); bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2); @@ -31,6 +33,13 @@ struct iovec* iovec_make_string(struct iovec *iovec, const char *s); .iov_len = 1, \ } +#define IOVEC_ALLOCA(n) \ + ({ \ + size_t _n_ = (n); \ + IOVEC_MAKE(alloca_safe(_n_), _n_); \ + }) + +void iovec_erase(struct iovec *iovec); void iovec_done_erase(struct iovec *iovec); char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); diff --git a/src/journal/journalctl-authenticate.c b/src/journal/journalctl-authenticate.c index b1b1ba6cd0..721404a1f5 100644 --- a/src/journal/journalctl-authenticate.c +++ b/src/journal/journalctl-authenticate.c @@ -15,6 +15,7 @@ #include "hostname-setup.h" #include "hostname-util.h" #include "io-util.h" +#include "iovec-util.h" #include "journal-def.h" #include "journalctl.h" #include "journalctl-authenticate.h" @@ -31,8 +32,7 @@ #if HAVE_GCRYPT static int format_key( - const void *seed, - size_t seed_size, + const struct iovec *seed, uint64_t start, uint64_t interval, char **ret) { @@ -40,18 +40,17 @@ static int format_key( _cleanup_(memstream_done) MemStream m = {}; FILE *f; - assert(seed); - assert(seed_size > 0); + assert(iovec_is_set(seed)); assert(ret); f = memstream_init(&m); if (!f) return -ENOMEM; - for (size_t i = 0; i < seed_size; i++) { + for (size_t i = 0; i < seed->iov_len; i++) { if (i > 0 && i % 3 == 0) fputc('-', f); - fprintf(f, "%02x", ((uint8_t*) seed)[i]); + fprintf(f, "%02x", ((uint8_t*) seed->iov_base)[i]); } fprintf(f, "/%"PRIx64"-%"PRIx64, start, interval); @@ -65,8 +64,6 @@ int action_setup_keys(void) { _cleanup_(unlink_and_freep) char *tmpfile = NULL; _cleanup_close_ int fd = -EBADF; _cleanup_free_ char *path = NULL; - size_t mpk_size, seed_size, state_size; - uint8_t *mpk, *seed, *state; sd_id128_t machine, boot; uint64_t n; int r; @@ -105,30 +102,26 @@ int action_setup_keys(void) { return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Sealing key file %s exists already. Use --force to recreate.", path); - mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR); - mpk = alloca_safe(mpk_size); - - seed_size = FSPRG_RECOMMENDED_SEEDLEN; - seed = alloca_safe(seed_size); - - state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); - state = alloca_safe(state_size); + _cleanup_(iovec_erase) struct iovec + mpk = IOVEC_ALLOCA(FSPRG_mpkinbytes(FSPRG_RECOMMENDED_SECPAR)), + seed = IOVEC_ALLOCA(FSPRG_RECOMMENDED_SEEDLEN), + state = IOVEC_ALLOCA(FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR)); if (!arg_quiet) log_info("Generating seed..."); - r = crypto_random_bytes(seed, seed_size); + r = crypto_random_bytes(seed.iov_base, seed.iov_len); if (r < 0) return log_error_errno(r, "Failed to acquire random seed: %m"); if (!arg_quiet) log_info("Generating key pair..."); - r = FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR); + r = FSPRG_GenMK(NULL, mpk.iov_base, seed.iov_base, seed.iov_len, FSPRG_RECOMMENDED_SECPAR); if (r < 0) return log_error_errno(r, "Failed to generate key pair: %m"); if (!arg_quiet) log_info("Generating sealing key..."); - r = FSPRG_GenState0(state, mpk, seed, seed_size); + r = FSPRG_GenState0(state.iov_base, mpk.iov_base, seed.iov_base, seed.iov_len); if (r < 0) return log_error_errno(r, "Failed to generate sealing key: %m"); @@ -146,21 +139,21 @@ int action_setup_keys(void) { r, "Failed to set file attributes on a temporary file for '%s', ignoring: %m", path); struct FSSHeader h = { - .signature = { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }, + .signature = FSS_HEADER_SIGNATURE, .machine_id = machine, .boot_id = boot, .header_size = htole64(sizeof(h)), .start_usec = htole64(n * arg_interval), .interval_usec = htole64(arg_interval), .fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR), - .fsprg_state_size = htole64(state_size), + .fsprg_state_size = htole64(state.iov_len), }; r = loop_write(fd, &h, sizeof(h)); if (r < 0) return log_error_errno(r, "Failed to write header: %m"); - r = loop_write(fd, state, state_size); + r = loop_write(fd, state.iov_base, state.iov_len); if (r < 0) return log_error_errno(r, "Failed to write state: %m"); @@ -170,8 +163,8 @@ int action_setup_keys(void) { tmpfile = mfree(tmpfile); - _cleanup_free_ char *key = NULL; - r = format_key(seed, seed_size, n, arg_interval, &key); + _cleanup_(erase_and_freep) char *key = NULL; + r = format_key(&seed, n, arg_interval, &key); if (r < 0) return r; @@ -240,7 +233,7 @@ int action_setup_keys(void) { fputs(ansi_normal(), stderr); #if HAVE_QRENCODE - _cleanup_free_ char *url = NULL; + _cleanup_(erase_and_freep) char *url = NULL; url = strjoin("fss://", key, "?machine=", SD_ID128_TO_STRING(machine), hn ? ";hostname=" : "", hn); if (!url) return log_oom(); diff --git a/src/journal/journalctl-misc.c b/src/journal/journalctl-misc.c index 78d3cae91a..be0b09d8fe 100644 --- a/src/journal/journalctl-misc.c +++ b/src/journal/journalctl-misc.c @@ -4,6 +4,7 @@ #include "alloc-util.h" #include "dirent-util.h" +#include "errno-util.h" #include "fd-util.h" #include "format-table.h" #include "format-util.h" @@ -35,7 +36,7 @@ int action_print_header(void) { int action_verify(void) { _cleanup_(sd_journal_closep) sd_journal *j = NULL; - int r; + int r, ret = 0; assert(arg_action == ACTION_VERIFY); @@ -47,43 +48,40 @@ int action_verify(void) { JournalFile *f; ORDERED_HASHMAP_FOREACH(f, j->files) { - int k; usec_t first = 0, validated = 0, last = 0; -#if HAVE_GCRYPT - if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) - log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path); -#endif - - k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, /* show_progress= */ !arg_quiet); - if (k == -EINVAL) + r = journal_file_verify(f, arg_verify_key, &first, &validated, &last, /* show_progress= */ !arg_quiet); + if (r == -EKEYREJECTED) /* If the key was invalid give up right-away. */ - return k; - if (k < 0) - r = log_warning_errno(k, "FAIL: %s (%m)", f->path); - else { - char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX]; - log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "PASS: %s", f->path); + return r; + if (r == -ENOKEY) + log_notice_errno(r, "Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path); + if (r < 0) { + RET_GATHER(ret, log_warning_errno(r, "FAIL: %s: %m", f->path)); + continue; + } - if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) { - if (validated > 0) { - log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, - "=> Validated from %s to %s, final %s entries not sealed.", - format_timestamp_maybe_utc(a, sizeof(a), first), - format_timestamp_maybe_utc(b, sizeof(b), validated), - FORMAT_TIMESPAN(last > validated ? last - validated : 0, 0)); - } else if (last > 0) - log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, - "=> No sealing yet, %s of entries not sealed.", - FORMAT_TIMESPAN(last - first, 0)); - else - log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, - "=> No sealing yet, no entries in file."); - } + log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "PASS: %s", f->path); + + if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) { + if (validated > 0) { + char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX]; + log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, + "=> Validated from %s to %s, final %s entries not sealed.", + format_timestamp_maybe_utc(a, sizeof(a), first), + format_timestamp_maybe_utc(b, sizeof(b), validated), + FORMAT_TIMESPAN(usec_sub_unsigned(last, validated), 0)); + } else if (last > 0) + log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, + "=> No sealing yet, %s of entries not sealed.", + FORMAT_TIMESPAN(usec_sub_unsigned(last, first), 0)); + else + log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, + "=> No sealing yet, no entries in file."); } } - return r; + return ret; } int action_disk_usage(void) { diff --git a/src/libsystemd/sd-journal/journal-authenticate.c b/src/libsystemd/sd-journal/journal-authenticate.c index 60a60f26f5..86be008aa1 100644 --- a/src/libsystemd/sd-journal/journal-authenticate.c +++ b/src/libsystemd/sd-journal/journal-authenticate.c @@ -9,6 +9,7 @@ #include "fsprg.h" #include "gcrypt-util.h" #include "hexdecoct.h" +#include "iovec-util.h" #include "journal-authenticate.h" #include "journal-def.h" #include "journal-file.h" @@ -28,23 +29,8 @@ static void* fssheader_free(FSSHeader *p) { DEFINE_TRIVIAL_CLEANUP_FUNC(FSSHeader*, fssheader_free); -#if HAVE_GCRYPT -static uint64_t journal_file_tag_seqnum(JournalFile *f) { - uint64_t r; - - assert(f); - - r = le64toh(f->header->n_tags) + 1; - f->header->n_tags = htole64(r); - - return r; -} -#endif - int journal_file_append_tag(JournalFile *f) { #if HAVE_GCRYPT - Object *o; - uint64_t p; int r; assert(f); @@ -60,16 +46,20 @@ int journal_file_append_tag(JournalFile *f) { assert(f->hmac); + Object *o; + uint64_t p; r = journal_file_append_object(f, OBJECT_TAG, sizeof(struct TagObject), &o, &p); if (r < 0) return r; - o->tag.seqnum = htole64(journal_file_tag_seqnum(f)); - o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state)); + uint64_t seqnum = le64toh(f->header->n_tags) + 1; + f->header->n_tags = htole64(seqnum); + + o->tag.seqnum = htole64(seqnum); + o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state.iov_base)); log_debug("Writing tag %"PRIu64" for epoch %"PRIu64"", - le64toh(o->tag.seqnum), - FSPRG_GetEpoch(f->fsprg_state)); + le64toh(o->tag.seqnum), le64toh(o->tag.epoch)); /* Add the tag object itself, so that we can protect its * header. This will exclude the actual hash value in it */ @@ -89,8 +79,6 @@ int journal_file_append_tag(JournalFile *f) { int journal_file_hmac_start(JournalFile *f) { #if HAVE_GCRYPT - uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */ - gcry_error_t err; int r; assert(f); @@ -104,11 +92,13 @@ int journal_file_hmac_start(JournalFile *f) { /* Prepare HMAC for next cycle */ sym_gcry_md_reset(f->hmac); - r = FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0); + uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */ + CLEANUP_ERASE(key); + r = FSPRG_GetKey(f->fsprg_state.iov_base, key, sizeof(key), 0); if (r < 0) return r; - err = sym_gcry_md_setkey(f->hmac, key, sizeof(key)); + gcry_error_t err = sym_gcry_md_setkey(f->hmac, key, sizeof(key)); if (gcry_err_code(err) != GPG_ERR_NO_ERROR) return log_debug_errno(SYNTHETIC_ERRNO(EIO), "sym_gcry_md_setkey() failed with error code: %s", @@ -156,7 +146,7 @@ static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) { if (r < 0) return r; - epoch = FSPRG_GetEpoch(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state.iov_base); if (epoch > goal) return -ESTALE; @@ -176,7 +166,7 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) { if (r < 0) return r; - epoch = FSPRG_GetEpoch(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state.iov_base); if (epoch < goal) log_debug("Evolving FSPRG key from epoch %"PRIu64" to %"PRIu64".", epoch, goal); @@ -186,11 +176,11 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) { if (epoch == goal) return 0; - r = FSPRG_Evolve(f->fsprg_state); + r = FSPRG_Evolve(f->fsprg_state.iov_base); if (r < 0) return r; - epoch = FSPRG_GetEpoch(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state.iov_base); if (epoch < goal) { r = journal_file_append_tag(f); if (r < 0) @@ -200,8 +190,6 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) { } int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) { - void *msk; - uint64_t epoch; int r; assert(f); @@ -209,33 +197,31 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) { if (!JOURNAL_HEADER_SEALED(f->header)) return 0; - assert(f->fsprg_seed); + assert(iovec_is_set(&f->fsprg_seed)); - if (f->fsprg_state) { + if (iovec_is_set(&f->fsprg_state)) { /* Cheaper... */ - epoch = FSPRG_GetEpoch(f->fsprg_state); + uint64_t epoch = FSPRG_GetEpoch(f->fsprg_state.iov_base); if (goal == epoch) return 0; if (goal == epoch + 1) - return FSPRG_Evolve(f->fsprg_state); + return FSPRG_Evolve(f->fsprg_state.iov_base); } else { - f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); - f->fsprg_state = malloc(f->fsprg_state_size); - if (!f->fsprg_state) - return -ENOMEM; + r = iovec_alloc(FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR), &f->fsprg_state); + if (r < 0) + return r; } log_debug("Seeking FSPRG key to %"PRIu64".", goal); - msk = alloca_safe(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR)); - - r = FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR); + _cleanup_(iovec_erase) struct iovec msk = IOVEC_ALLOCA(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR)); + r = FSPRG_GenMK(msk.iov_base, NULL, f->fsprg_seed.iov_base, f->fsprg_seed.iov_len, FSPRG_RECOMMENDED_SECPAR); if (r < 0) return r; - return FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size); + return FSPRG_Seek(f->fsprg_state.iov_base, goal, msk.iov_base, f->fsprg_seed.iov_base, f->fsprg_seed.iov_len); } int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) { @@ -396,7 +382,7 @@ int journal_file_fss_load(JournalFile *f) { if (header == MAP_FAILED) return -errno; - if (memcmp(header->signature, FSS_HEADER_SIGNATURE, 8) != 0) + if (memcmp(header->signature, (const uint8_t[]) FSS_HEADER_SIGNATURE, 8) != 0) return -EBADMSG; if (header->incompatible_flags != 0) @@ -429,8 +415,9 @@ int journal_file_fss_load(JournalFile *f) { f->fss_start_usec = le64toh(f->fss_file->start_usec); f->fss_interval_usec = le64toh(f->fss_file->interval_usec); - f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size); - f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size); + f->fsprg_state = IOVEC_MAKE( + (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size), + le64toh(f->fss_file->fsprg_state_size)); return 0; } @@ -496,10 +483,9 @@ int journal_file_append_first_tag(JournalFile *f) { } int journal_file_parse_verification_key(JournalFile *f, const char *key) { - _cleanup_free_ uint8_t *seed = NULL; + _cleanup_(erase_and_freep) uint8_t *seed = NULL; size_t seed_size; const char *k; - unsigned long long start, interval; int r; assert(f); @@ -518,29 +504,35 @@ int journal_file_parse_verification_key(JournalFile *f, const char *key) { x = unhexchar(*k); if (x < 0) - return -EINVAL; + return -EKEYREJECTED; k++; y = unhexchar(*k); if (y < 0) - return -EINVAL; + return -EKEYREJECTED; k++; seed[c] = (uint8_t) (x * 16 + y); } if (*k != '/') - return -EINVAL; + return -EKEYREJECTED; k++; - r = sscanf(k, "%llx-%llx", &start, &interval); + uint64_t start, interval; + r = sscanf(k, "%"PRIx64"-%"PRIx64, &start, &interval); if (r != 2) - return -EINVAL; + return -EKEYREJECTED; - f->fsprg_seed = TAKE_PTR(seed); - f->fsprg_seed_size = seed_size; + if (start == 0 || interval == 0) + return -EKEYREJECTED; - f->fss_start_usec = start * interval; + uint64_t start_usec; + if (!MUL_SAFE(&start_usec, start, interval)) + return -EKEYREJECTED; + + f->fsprg_seed = IOVEC_MAKE(TAKE_PTR(seed), seed_size); + f->fss_start_usec = start_usec; f->fss_interval_usec = interval; return 0; @@ -555,7 +547,7 @@ bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) { if (!JOURNAL_HEADER_SEALED(f->header)) return false; - epoch = FSPRG_GetEpoch(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state.iov_base); *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec); diff --git a/src/libsystemd/sd-journal/journal-def.h b/src/libsystemd/sd-journal/journal-def.h index 84849a1e95..026aa4c941 100644 --- a/src/libsystemd/sd-journal/journal-def.h +++ b/src/libsystemd/sd-journal/journal-def.h @@ -261,7 +261,7 @@ assert_cc(sizeof(struct Header) == sizeof(struct Header__packed)); assert_cc(sizeof(struct Header) == 272); #define FSS_HEADER_SIGNATURE \ - ((const char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }) + { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' } struct FSSHeader { uint8_t signature[8]; /* "KSHHRHLP" */ diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 78d94f10bd..37392ea9bb 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -22,6 +22,7 @@ #include "gcrypt-util.h" #include "hashmap.h" #include "id128-util.h" +#include "iovec-util.h" #include "journal-authenticate.h" #include "journal-def.h" #include "journal-file.h" @@ -312,9 +313,9 @@ JournalFile* journal_file_close(JournalFile *f) { assert(sz < SIZE_MAX); munmap(f->fss_file, sz); } else - free(f->fsprg_state); + iovec_done_erase(&f->fsprg_state); - free(f->fsprg_seed); + iovec_done_erase(&f->fsprg_seed); if (f->hmac) sym_gcry_md_close(f->hmac); diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h index b3a620200a..fea181cafd 100644 --- a/src/libsystemd/sd-journal/journal-file.h +++ b/src/libsystemd/sd-journal/journal-file.h @@ -107,11 +107,8 @@ typedef struct JournalFile { uint64_t fss_start_usec; uint64_t fss_interval_usec; - void *fsprg_state; - size_t fsprg_state_size; - - void *fsprg_seed; - size_t fsprg_seed_size; + struct iovec fsprg_state; + struct iovec fsprg_seed; /* When we insert this file into the per-boot priority queue 'newest_by_boot_id' in sd_journal, then by these keys */ sd_id128_t newest_boot_id; diff --git a/src/libsystemd/sd-journal/journal-verify.c b/src/libsystemd/sd-journal/journal-verify.c index 11532c5f8a..02420840df 100644 --- a/src/libsystemd/sd-journal/journal-verify.c +++ b/src/libsystemd/sd-journal/journal-verify.c @@ -814,12 +814,14 @@ static int verify_hash_table( int journal_file_verify( JournalFile *f, const char *key, - usec_t *first_contained, usec_t *last_validated, usec_t *last_contained, + usec_t *ret_first_contained, + usec_t *ret_last_validated, + usec_t *ret_last_contained, bool show_progress) { + int r; Object *o; - uint64_t p = 0, last_epoch = 0, last_tag_realtime = 0; - + uint64_t p = 0, last_epoch = 0, last_tag_realtime = 0, last_tag_realtime_end = 0; uint64_t entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0; usec_t min_entry_realtime = USEC_INFINITY, max_entry_realtime = 0; sd_id128_t entry_boot_id = {}; /* Unnecessary initialization to appease gcc */ @@ -842,10 +844,8 @@ int journal_file_verify( if (key) { #if HAVE_GCRYPT r = journal_file_parse_verification_key(f, key); - if (r < 0) { - log_error("Failed to parse seed."); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to load verification key: %m"); #else return -EOPNOTSUPP; #endif @@ -1167,7 +1167,7 @@ int journal_file_verify( error(p, "tag/entry realtime timestamp out of synchronization (%"PRIu64" >= %"PRIu64")", entry_realtime, - rt + f->fss_interval_usec); + rt_end); r = -EBADMSG; goto fail; } @@ -1234,6 +1234,7 @@ int journal_file_verify( f->hmac_running = false; last_tag_realtime = rt; + last_tag_realtime_end = rt_end; } last_tag = p + ALIGN64(le64toh(o->object.size)); @@ -1404,14 +1405,12 @@ int journal_file_verify( mmap_cache_fd_free(cache_entry_fd); mmap_cache_fd_free(cache_entry_array_fd); - if (first_contained) - *first_contained = le64toh(f->header->head_entry_realtime); -#if HAVE_GCRYPT - if (last_validated) - *last_validated = last_tag_realtime + f->fss_interval_usec; -#endif - if (last_contained) - *last_contained = le64toh(f->header->tail_entry_realtime); + if (ret_first_contained) + *ret_first_contained = le64toh(f->header->head_entry_realtime); + if (ret_last_validated) + *ret_last_validated = last_tag_realtime_end; + if (ret_last_contained) + *ret_last_contained = le64toh(f->header->tail_entry_realtime); return 0; diff --git a/src/libsystemd/sd-journal/journal-verify.h b/src/libsystemd/sd-journal/journal-verify.h index 579033069b..46d323df83 100644 --- a/src/libsystemd/sd-journal/journal-verify.h +++ b/src/libsystemd/sd-journal/journal-verify.h @@ -3,4 +3,10 @@ #include "journal-file.h" -int journal_file_verify(JournalFile *f, const char *key, usec_t *first_contained, usec_t *last_validated, usec_t *last_contained, bool show_progress); +int journal_file_verify( + JournalFile *f, + const char *key, + usec_t *ret_first_contained, + usec_t *ret_last_validated, + usec_t *ret_last_contained, + bool show_progress); diff --git a/src/shared/journal-importer.c b/src/shared/journal-importer.c index 471ad879a4..128866e17c 100644 --- a/src/shared/journal-importer.c +++ b/src/shared/journal-importer.c @@ -292,7 +292,7 @@ int journal_importer_process_data(JournalImporter *imp) { switch (imp->state) { case IMPORTER_STATE_LINE: { - char *line, *sep; + char *line = NULL; /* avoid false maybe-uninitialized warning */ size_t n = 0; assert(imp->data_size == 0); @@ -317,7 +317,7 @@ int journal_importer_process_data(JournalImporter *imp) { COREDUMP\n LLLLLLLL0011223344...\n */ - sep = memchr(line, '=', n); + char *sep = memchr(line, '=', n); if (sep) { /* chomp newline */ n--;