journal-verify.c revision c0ca7aeec963207b6fa5ee39bd204cb26cba4023
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/***
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2012 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen***/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <unistd.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/mman.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <fcntl.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <stddef.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "util.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "macro.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "journal-def.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "journal-file.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "journal-authenticate.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "journal-verify.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "lookup3.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "compress.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "fsprg.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poetteringstatic int journal_file_object_verify(JournalFile *f, Object *o) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering uint64_t i;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* This does various superficial tests about the length an
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * possible field values. It does not follow any references to
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * other objects. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((o->object.flags & OBJECT_COMPRESSED) &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen o->object.type != OBJECT_DATA)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering switch (o->object.type) {
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering case OBJECT_DATA: {
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering uint64_t h1, h2;
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->data.entry_offset) <= 0 ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(o->data.n_entries) <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen h1 = le64toh(o->data.hash);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (o->object.flags & OBJECT_COMPRESSED) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen void *b = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t alloc = 0, b_size;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (!uncompress_blob(o->data.payload,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(o->object.size) - offsetof(Object, data.payload),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &b, &alloc, &b_size))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen h2 = hash64(b, b_size);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(b);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen if (h1 != h2)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!VALID64(o->data.next_hash_offset) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID64(o->data.next_field_offset) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID64(o->data.entry_offset) ||
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek !VALID64(o->data.entry_array_offset))
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek break;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek }
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek case OBJECT_FIELD:
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0)
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (!VALID64(o->field.next_hash_offset) ||
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek !VALID64(o->field.head_data_offset))
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek break;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek case OBJECT_ENTRY:
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0)
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0)
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (le64toh(o->entry.seqnum) <= 0 ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID_REALTIME(le64toh(o->entry.realtime)) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID_MONOTONIC(le64toh(o->entry.monotonic)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < journal_file_entry_n_items(o); i++) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (o->entry.items[i].object_offset == 0 ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID64(o->entry.items[i].object_offset))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_DATA_HASH_TABLE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_FIELD_HASH_TABLE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (o->hash_table.items[i].head_hash_offset != 0 &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID64(le64toh(o->hash_table.items[i].head_hash_offset)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (o->hash_table.items[i].tail_hash_offset != 0 &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if ((o->hash_table.items[i].head_hash_offset != 0) !=
b7e7184634d573fb73143210962acce205f37f61Michael Biebl (o->hash_table.items[i].tail_hash_offset != 0))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return -EBADMSG;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl }
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl break;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl case OBJECT_ENTRY_ARRAY:
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return -EBADMSG;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return -EBADMSG;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (!VALID64(o->entry_array.next_entry_array_offset))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return -EBADMSG;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl for (i = 0; i < journal_file_entry_array_n_items(o); i++)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (o->entry_array.items[i] != 0 &&
b7e7184634d573fb73143210962acce205f37f61Michael Biebl !VALID64(o->entry_array.items[i]))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek case OBJECT_TAG:
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (le64toh(o->object.size) != sizeof(TagObject))
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!VALID_EPOCH(o->tag.epoch))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pittstatic void draw_progress(uint64_t p, usec_t *last_usec) {
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt unsigned n, i, j, k;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt usec_t z, x;
4e5589836c9e143796c3f3d81e67ab7a9209e2b0Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt if (!isatty(STDOUT_FILENO))
9993ef2e9817b35b1d467707bef12b2a140b62dcLennart Poettering return;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt z = now(CLOCK_MONOTONIC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen x = *last_usec;
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (x != 0 && x + 40 * USEC_PER_MSEC > z)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen *last_usec = z;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
aad0a2c80097926757d4385e5f5492082d47f006Zbigniew Jędrzejewski-Szmek n = (3 * columns()) / 4;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen j = (n * (unsigned) p) / 65535ULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k = n - j;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < j; i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fputs("\xe2\x96\x88", stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen fputs(ANSI_HIGHLIGHT_OFF, stdout);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < k; i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fputs("\xe2\x96\x91", stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf(" %3lu%%", 100LU * (unsigned long) p / 65535LU);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fputs("\r\x1B[?25h", stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fflush(stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void flush_progress(void) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned n, i;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!isatty(STDOUT_FILENO))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen n = (3 * columns()) / 4;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen putchar('\r');
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < n + 5; i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen putchar(' ');
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen putchar('\r');
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fflush(stdout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int write_uint64(int fd, uint64_t p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ssize_t k;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k = write(fd, &p, sizeof(p));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (k < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -errno;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (k != sizeof(p))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EIO;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t a, b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(m);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(fd >= 0);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann /* Bisection ... */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler a = 0; b = n;
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler while (a < b) {
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann uint64_t c, *z;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann c = (a + b) / 2;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann return r;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann if (*z == p)
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann return 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (a + 1 >= b)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p < *z)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = c;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a = c;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int entry_points_to_data(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JournalFile *f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int entry_fd,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t n_entries,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t entry_p,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t data_p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering uint64_t i, n, a;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o;
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering bool found = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(entry_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Data object references invalid entry at %llu", (unsigned long long) data_p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_ENTRY, entry_p, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = journal_file_entry_n_items(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < n; i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->entry.items[i].object_offset) == data_p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen found = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!found) {
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt log_error("Data object not referenced by linked entry at %llu", (unsigned long long) data_p);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering return -EBADMSG;
40780877c19ef408da8ab21f4156cfc153f94b5cMartin Pitt }
3315f085178f46155fda345d9526c09083b45946Lennart Poettering
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering /* Check if this entry is also in main entry array. Since the
3315f085178f46155fda345d9526c09083b45946Lennart Poettering * main entry array has already been verified we can rely on
3315f085178f46155fda345d9526c09083b45946Lennart Poettering * its consistency.*/
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen i = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = le64toh(f->header->n_entries);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a = le64toh(f->header->entry_array_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering while (i < n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t m, u;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering if (r < 0)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return r;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
3315f085178f46155fda345d9526c09083b45946Lennart Poettering m = journal_file_entry_array_n_items(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen u = MIN(n - i, m);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_p <= le64toh(o->entry_array.items[u-1])) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t x, y, z;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen x = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen y = u;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while (x < y) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen z = (x + y) / 2;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->entry_array.items[z]) == entry_p)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (x + 1 >= y)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek break;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (entry_p < le64toh(o->entry_array.items[z]))
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek y = z;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek else
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek x = z;
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_error("Entry object doesn't exist in main entry array at %llu", (unsigned long long) entry_p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return -EBADMSG;
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek i += u;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek a = le64toh(o->entry_array.next_entry_array_offset);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Satelerstatic int verify_data(
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek JournalFile *f,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek Object *o, uint64_t p,
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek int entry_fd, uint64_t n_entries,
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering int entry_array_fd, uint64_t n_entry_arrays) {
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek uint64_t i, n, a, last, q;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(f);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(o);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(entry_fd >= 0);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(entry_array_fd >= 0);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek n = le64toh(o->data.n_entries);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek a = le64toh(o->data.entry_array_offset);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek /* We already checked this earlier */
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(n > 0);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek last = q = le64toh(o->data.entry_offset);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = entry_points_to_data(f, entry_fd, n_entries, q, p);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann if (r < 0)
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler return r;
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler i = 1;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek while (i < n) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek uint64_t next, m, j;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (a == 0) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_error("Array chain too short at %llu", (unsigned long long) p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return -EBADMSG;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_error("Invalid array at %llu", (unsigned long long) p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return -EBADMSG;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (r < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek next = le64toh(o->entry_array.next_entry_array_offset);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (next != 0 && next <= a) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_error("Array chain has cycle at %llu", (unsigned long long) p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return -EBADMSG;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek m = journal_file_entry_array_n_items(o);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek for (j = 0; i < n && j < m; i++, j++) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek q = le64toh(o->entry_array.items[j]);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (q <= last) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_error("Data object's entry array not sorted at %llu", (unsigned long long) p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return -EBADMSG;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek last = q;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = entry_points_to_data(f, entry_fd, n_entries, q, p);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (r < 0)
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek return r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek /* Pointer might have moved, reposition */
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek if (r < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek a = next;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int verify_hash_table(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JournalFile *f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int data_fd, uint64_t n_data,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int entry_fd, uint64_t n_entries,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int entry_array_fd, uint64_t n_entry_arrays,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t *last_usec,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool show_progress) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t i, n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(entry_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(entry_array_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(last_usec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt for (i = 0; i < n; i++) {
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt uint64_t last = 0, p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (show_progress)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = le64toh(f->data_hash_table[i].head_hash_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while (p != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering uint64_t next;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid data object at hash entry %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen next = le64toh(o->data.next_hash_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (next != 0 && next <= p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Hash chain has a cycle in hash entry %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->data.hash) % n != i) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Hash value mismatch in hash entry %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen last = p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = next;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Tail hash pointer mismatch in hash table");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t n, h, q;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen h = hash % n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = le64toh(f->data_hash_table[h].head_hash_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while (q != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p == q)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_DATA, q, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = le64toh(o->data.next_hash_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int verify_entry(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JournalFile *f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o, uint64_t p,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int data_fd, uint64_t n_data) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering uint64_t i, n;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(data_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = journal_file_entry_n_items(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < n; i++) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t q, h;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *u;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = le64toh(o->entry.items[i].object_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen h = le64toh(o->entry.items[i].hash);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid data object at entry %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_DATA, q, &u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(u->data.hash) != h) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Hash mismatch for data object at entry %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = data_object_in_hash_table(f, h, q);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r == 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Data object missing from hash at entry %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int verify_entry_array(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JournalFile *f,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int data_fd, uint64_t n_data,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int entry_fd, uint64_t n_entries,
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int entry_array_fd, uint64_t n_entry_arrays,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t *last_usec,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool show_progress) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t i = 0, a, n, last = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(data_fd >= 0);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(entry_fd >= 0);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(entry_array_fd >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(last_usec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n = le64toh(f->header->n_entries);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a = le64toh(f->header->entry_array_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while (i < n) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t next, m, j;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (show_progress)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (a == 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Array chain too short at %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid array at %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen next = le64toh(o->entry_array.next_entry_array_offset);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (next != 0 && next <= a) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Array chain has cycle at %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen m = journal_file_entry_array_n_items(o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (j = 0; i < n && j < m; i++, j++) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = le64toh(o->entry_array.items[j]);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p <= last) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Entry array not sorted at %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen last = p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid array entry at %llu of %llu",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (unsigned long long) i, (unsigned long long) n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = verify_entry(f, o, p, data_fd, n_data);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Pointer might have moved, reposition */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a = next;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint journal_file_verify(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JournalFile *f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *key,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t *first_validated, usec_t *last_validated, usec_t *last_contained,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool show_progress) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Object *o;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0, last_sealed_realtime = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen uint64_t entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_id128_t entry_boot_id;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen 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;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t last_usec = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char data_path[] = "/var/tmp/journal-data-XXXXXX",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_path[] = "/var/tmp/journal-entry-XXXXXX",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX";
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unsigned i;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool found_last;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (key) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#ifdef HAVE_GCRYPT
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_parse_verification_key(f, key);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to parse seed.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -ENOTSUP;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#endif
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (f->seal)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -ENOKEY;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen data_fd = mkostemp(data_path, O_CLOEXEC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (data_fd < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to create data file: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -errno;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unlink(data_path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_fd = mkostemp(entry_path, O_CLOEXEC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_fd < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to create entry file: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -errno;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unlink(entry_path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_array_fd < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Failed to create entry array file: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -errno;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek unlink(entry_array_path);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#ifdef HAVE_GCRYPT
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f->header->compatible_flags != 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#endif
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Cannot verify file with unknown extensions.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -ENOTSUP;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < sizeof(f->header->reserved); i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f->header->reserved[i] != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Reserved field in non-zero.");
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek r = -EBADMSG;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering /* First iteration: we go through all objects, verify the
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering * superficial structure, headers, hashes. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering p = le64toh(f->header->header_size);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering while (p != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (show_progress)
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, -1, p, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid object at %llu", (unsigned long long) p);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering goto fail;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering }
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p > le64toh(f->header->tail_object_offset)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Invalid tail object pointer");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering }
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering if (p == le64toh(f->header->tail_object_offset))
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering found_last = true;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering n_objects ++;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek r = journal_file_object_verify(f, o);
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt if (r < 0) {
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt log_error("Invalid object contents at %llu", (unsigned long long) p);
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt goto fail;
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Compressed object in file without compression at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (o->object.type) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering case OBJECT_DATA:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = write_uint64(data_fd, p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_data++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_FIELD:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_fields++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_ENTRY:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("First entry before first tag at %llu", (unsigned long long) p);
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = write_uint64(entry_fd, p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->entry.realtime) < last_tag_realtime) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Older entry after newer tag at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!entry_seqnum_set &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Head entry sequence number incorrect at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_seqnum_set &&
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt entry_seqnum >= le64toh(o->entry.seqnum)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Entry sequence number out of synchronization at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen entry_seqnum = le64toh(o->entry.seqnum);
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen entry_seqnum_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_monotonic_set &&
a34bf9db5da0fdd6bdb14459e203dbe41ee99614Lennart Poettering sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_monotonic > le64toh(o->entry.monotonic)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Entry timestamp out of synchronization at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_monotonic = le64toh(o->entry.monotonic);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_boot_id = o->entry.boot_id;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_monotonic_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!entry_realtime_set &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Head entry realtime timestamp incorrect");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_realtime = le64toh(o->entry.realtime);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen entry_realtime_set = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_entries ++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_DATA_HASH_TABLE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (n_data_hash_tables > 1) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("More than one data hash table at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen goto fail;
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen }
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Header fields for data hash table invalid");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_data_hash_tables++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_FIELD_HASH_TABLE:
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (n_field_hash_tables > 1) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("More than one field hash table at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Header fields for field hash table invalid");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_field_hash_tables++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_ENTRY_ARRAY:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = write_uint64(entry_array_fd, p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p == le64toh(f->header->entry_array_offset)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (found_main_entry_array) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("More than one main entry array at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen found_main_entry_array = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen n_entry_arrays++;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case OBJECT_TAG:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!JOURNAL_HEADER_SEALED(f->header)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->tag.seqnum) != n_tags + 1) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (le64toh(o->tag.epoch) < last_epoch) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Epoch sequence out of synchronization at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#ifdef HAVE_GCRYPT
f8bc41822ba19905707a97f9d87262f2c2b6e5faZbigniew Jędrzejewski-Szmek if (f->seal) {
5921fc3cc36df4baa5e16060e7675ace9eda2befThomas Hindoe Paaboel Andersen uint64_t q, rt;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* OK, now we know the epoch. So let's now set
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * it, and calculate the HMAC for everything
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * since the last tag. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_fsprg_seek(f, le64toh(o->tag.epoch));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering r = journal_file_hmac_start(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (last_tag == 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_hmac_put_header(f);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = le64toh(f->header->header_size);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = last_tag;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while (q <= p) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = journal_file_move_to_object(f, -1, q, &o);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek r = journal_file_hmac_put_object(f, -1, q);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = q + ALIGN64(le64toh(o->object.size));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering /* Position might have changed, let's reposition things */
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering r = journal_file_move_to_object(f, -1, p, &o);
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering if (r < 0)
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering goto fail;
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error("Tag failed verification at %llu", (unsigned long long) p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f->hmac_running = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen last_tag_realtime = rt;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen last_sealed_realtime = entry_realtime;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#endif
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
last_tag = p + ALIGN64(le64toh(o->object.size));
last_epoch = le64toh(o->tag.epoch);
n_tags ++;
break;
default:
n_weird ++;
}
if (p == le64toh(f->header->tail_object_offset))
p = 0;
else
p = p + ALIGN64(le64toh(o->object.size));
}
if (!found_last) {
log_error("Tail object pointer dead");
r = -EBADMSG;
goto fail;
}
if (n_objects != le64toh(f->header->n_objects)) {
log_error("Object number mismatch");
r = -EBADMSG;
goto fail;
}
if (n_entries != le64toh(f->header->n_entries)) {
log_error("Entry number mismatch");
r = -EBADMSG;
goto fail;
}
if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
n_data != le64toh(f->header->n_data)) {
log_error("Data number mismatch");
r = -EBADMSG;
goto fail;
}
if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
n_fields != le64toh(f->header->n_fields)) {
log_error("Field number mismatch");
r = -EBADMSG;
goto fail;
}
if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
n_tags != le64toh(f->header->n_tags)) {
log_error("Tag number mismatch");
r = -EBADMSG;
goto fail;
}
if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) &&
n_entry_arrays != le64toh(f->header->n_entry_arrays)) {
log_error("Entry array number mismatch");
r = -EBADMSG;
goto fail;
}
if (n_data_hash_tables != 1) {
log_error("Missing data hash table");
r = -EBADMSG;
goto fail;
}
if (n_field_hash_tables != 1) {
log_error("Missing field hash table");
r = -EBADMSG;
goto fail;
}
if (!found_main_entry_array) {
log_error("Missing entry array");
r = -EBADMSG;
goto fail;
}
if (entry_seqnum_set &&
entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
log_error("Invalid tail seqnum");
r = -EBADMSG;
goto fail;
}
if (entry_monotonic_set &&
(!sd_id128_equal(entry_boot_id, f->header->boot_id) ||
entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
log_error("Invalid tail monotonic timestamp");
r = -EBADMSG;
goto fail;
}
if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
log_error("Invalid tail realtime timestamp");
r = -EBADMSG;
goto fail;
}
/* Second iteration: we follow all objects referenced from the
* two entry points: the object hash table and the entry
* array. We also check that everything referenced (directly
* or indirectly) in the data hash table also exists in the
* entry array, and vice versa. Note that we do not care for
* unreferenced objects. We only care that everything that is
* referenced is consistent. */
r = verify_entry_array(f,
data_fd, n_data,
entry_fd, n_entries,
entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
goto fail;
r = verify_hash_table(f,
data_fd, n_data,
entry_fd, n_entries,
entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
goto fail;
if (show_progress)
flush_progress();
mmap_cache_close_fd(f->mmap, data_fd);
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);
if (first_validated)
*first_validated = last_sealed_realtime > 0 ? le64toh(f->header->head_entry_realtime) : 0;
if (last_validated)
*last_validated = last_sealed_realtime;
if (last_contained)
*last_contained = le64toh(f->header->tail_entry_realtime);
return 0;
fail:
if (show_progress)
flush_progress();
log_error("File corruption detected at %s:%llu (of %llu, %llu%%).",
f->path,
(unsigned long long) p,
(unsigned long long) f->last_stat.st_size,
(unsigned long long) (100 * p / f->last_stat.st_size));
if (data_fd >= 0) {
mmap_cache_close_fd(f->mmap, data_fd);
close_nointr_nofail(data_fd);
}
if (entry_fd >= 0) {
mmap_cache_close_fd(f->mmap, entry_fd);
close_nointr_nofail(entry_fd);
}
if (entry_array_fd >= 0) {
mmap_cache_close_fd(f->mmap, entry_array_fd);
close_nointr_nofail(entry_array_fd);
}
return r;
}