journal-verify.c revision 7517e17443225fafea86b21e42a36af69feb1dbc
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2012 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void draw_progress(uint64_t p, usec_t *last_usec) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned n, i, j, k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x != 0 && x + 40 * USEC_PER_MSEC > z)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering j = (n * (unsigned) p) / 65535ULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (i = 0; i < j; i++)
static void flush_progress(void) {
if (!on_tty())
flush_progress(); \
flush_progress(); \
flush_progress(); \
uint64_t i;
assert(f);
assert(o);
return -EBADMSG;
case OBJECT_DATA: {
int compression, r;
return -EBADMSG;
return -EBADMSG;
if (compression) {
return -EBADMSG;
error(offset, "invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
return -EBADMSG;
case OBJECT_FIELD:
return -EBADMSG;
return -EBADMSG;
case OBJECT_ENTRY:
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
for (i = 0; i < journal_file_entry_n_items(o); i++) {
i, journal_file_entry_n_items(o),
return -EBADMSG;
case OBJECT_DATA_HASH_TABLE:
case OBJECT_FIELD_HASH_TABLE:
return -EBADMSG;
for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
return -EBADMSG;
return -EBADMSG;
"invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
return -EBADMSG;
case OBJECT_ENTRY_ARRAY:
return -EBADMSG;
return -EBADMSG;
for (i = 0; i < journal_file_entry_array_n_items(o); i++)
return -EBADMSG;
case OBJECT_TAG:
return -EBADMSG;
return -EBADMSG;
ssize_t k;
return -errno;
return -EIO;
uint64_t a, b;
assert(m);
uint64_t c, *z;
r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z, NULL);
static int entry_points_to_data(
JournalFile *f,
int entry_fd,
uint64_t i, n, a;
Object *o;
bool found = false;
assert(f);
return -EBADMSG;
n = journal_file_entry_n_items(o);
found = true;
if (!found) {
return -EBADMSG;
uint64_t m, u;
m = journal_file_entry_array_n_items(o);
u = MIN(n - i, m);
uint64_t x, y, z;
return -EBADMSG;
static int verify_data(
JournalFile *f,
assert(f);
assert(o);
error(p,
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
a, next);
return -EBADMSG;
m = journal_file_entry_array_n_items(o);
if (q <= last) {
return -EBADMSG;
last = q;
a = next;
static int verify_hash_table(
JournalFile *f,
bool show_progress) {
uint64_t i, n;
assert(f);
if (show_progress)
Object *o;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
last = p;
p = next;
return -EBADMSG;
uint64_t n, h, q;
assert(f);
h = hash % n;
Object *o;
static int verify_entry(
JournalFile *f,
uint64_t i, n;
assert(f);
assert(o);
n = journal_file_entry_n_items(o);
uint64_t q, h;
Object *u;
return -EBADMSG;
return -EBADMSG;
r = data_object_in_hash_table(f, h, q);
return -EBADMSG;
static int verify_entry_array(
JournalFile *f,
bool show_progress) {
assert(f);
Object *o;
if (show_progress)
return -EBADMSG;
return -EBADMSG;
error(a,
i, n, next);
return -EBADMSG;
m = journal_file_entry_array_n_items(o);
uint64_t p;
if (p <= last) {
return -EBADMSG;
last = p;
return -EBADMSG;
a = next;
int journal_file_verify(
JournalFile *f,
const char *key,
bool show_progress) {
Object *o;
bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
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;
bool found_last = false;
#ifdef HAVE_GCRYPT
assert(f);
if (key) {
#ifdef HAVE_GCRYPT
return -ENOTSUP;
} else if (f->seal)
return -ENOKEY;
if (data_fd < 0) {
r = -errno;
goto fail;
if (entry_fd < 0) {
r = -errno;
goto fail;
if (entry_array_fd < 0) {
r = -errno;
goto fail;
r = -ENOTSUP;
goto fail;
r = -EBADMSG;
goto fail;
if (show_progress)
goto fail;
r = -EBADMSG;
goto fail;
found_last = true;
n_objects ++;
r = journal_file_object_verify(f, p, o);
goto fail;
r = -EINVAL;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
case OBJECT_DATA:
goto fail;
n_data++;
case OBJECT_FIELD:
n_fields++;
case OBJECT_ENTRY:
r = -EBADMSG;
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
if (!entry_seqnum_set &&
r = -EBADMSG;
goto fail;
if (entry_seqnum_set &&
r = -EBADMSG;
goto fail;
entry_seqnum_set = true;
if (entry_monotonic_set &&
r = -EBADMSG;
goto fail;
entry_monotonic_set = true;
if (!entry_realtime_set &&
r = -EBADMSG;
goto fail;
entry_realtime_set = true;
n_entries ++;
case OBJECT_DATA_HASH_TABLE:
r = -EBADMSG;
goto fail;
le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
r = -EBADMSG;
goto fail;
case OBJECT_FIELD_HASH_TABLE:
r = -EBADMSG;
goto fail;
le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
r = -EBADMSG;
goto fail;
case OBJECT_ENTRY_ARRAY:
goto fail;
if (found_main_entry_array) {
r = -EBADMSG;
goto fail;
found_main_entry_array = true;
case OBJECT_TAG:
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
#ifdef HAVE_GCRYPT
if (f->seal) {
r = -EBADMSG;
goto fail;
goto fail;
r = journal_file_hmac_start(f);
goto fail;
if (last_tag == 0) {
r = journal_file_hmac_put_header(f);
goto fail;
q = last_tag;
goto fail;
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
f->hmac_running = false;
n_tags ++;
n_weird ++;
if (!found_last) {
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
if (!found_main_entry_array) {
r = -EBADMSG;
goto fail;
if (entry_seqnum_set &&
r = -EBADMSG;
goto fail;
if (entry_monotonic_set &&
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = verify_entry_array(f,
goto fail;
r = verify_hash_table(f,
goto fail;
if (show_progress)
if (first_contained)
if (last_validated)
if (last_contained)
fail:
if (show_progress)
f->path,
if (data_fd >= 0) {
if (entry_fd >= 0) {
if (entry_array_fd >= 0) {