journal: several cleanups for journal sealing feature (#42770)

This commit is contained in:
Yu Watanabe
2026-06-27 23:01:09 +09:00
committed by GitHub
11 changed files with 153 additions and 138 deletions
+20
View File
@@ -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);
+9
View File
@@ -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);
+18 -25
View File
@@ -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();
+29 -31
View File
@@ -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) {
@@ -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);
+1 -1
View File
@@ -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" */
+3 -2
View File
@@ -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);
+2 -5
View File
@@ -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;
+15 -16
View File
@@ -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;
+7 -1
View File
@@ -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);
+2 -2
View File
@@ -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--;