journal-verify.c revision 86adf873be22a38dbc9c6e86124c30b6caecd185
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers This file is part of systemd.
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers Copyright 2012 Lennart Poettering
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers systemd is free software; you can redistribute it and/or modify it
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers under the terms of the GNU Lesser General Public License as published by
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers the Free Software Foundation; either version 2.1 of the License, or
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers (at your option) any later version.
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers systemd is distributed in the hope that it will be useful, but
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers WITHOUT ANY WARRANTY; without even the implied warranty of
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers Lesser General Public License for more details.
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers You should have received a copy of the GNU Lesser General Public License
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers along with systemd; If not, see <http://www.gnu.org/licenses/>.
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * - verify FSPRG
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * - Allow building without libgcrypt
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * - check with sparse
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * - 64bit conversions
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * - verification should use MAP_PRIVATE
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sieversstatic int journal_file_object_verify(JournalFile *f, Object *o) {
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers /* This does various superficial tests about the length an
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * possible field values. It does not follow any references to
5ba2dc259f3cdd8fddef68cfd28380a32534e49aKay Sievers * other objects. */
8f0e73f250f4a397ea07d29a339bd7e64d077612Dave Reisner if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0)
return -EBADMSG;
free(b);
return -EBADMSG;
case OBJECT_FIELD:
return -EBADMSG;
case OBJECT_ENTRY:
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
case OBJECT_DATA_HASH_TABLE:
case OBJECT_FIELD_HASH_TABLE:
return -EBADMSG;
return -EBADMSG;
case OBJECT_ENTRY_ARRAY:
return -EBADMSG;
return -EBADMSG;
case OBJECT_TAG:
return -EBADMSG;
usec_t z, x;
x = *last_usec;
*last_usec = z;
static void flush_progress(void) {
ssize_t k;
return -errno;
return -EIO;
uint64_t a, b;
assert(m);
uint64_t c, *z;
r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, c * sizeof(uint64_t), sizeof(uint64_t), (void **) &z);
static int entry_points_to_data(
JournalFile *f,
int entry_fd,
uint64_t i, n, a;
Object *o;
bool found = false;
assert(f);
return -EBADMSG;
n = journal_file_entry_n_items(o);
found = true;
if (!found) {
return -EBADMSG;
uint64_t m, j;
m = journal_file_entry_array_n_items(o);
static int verify_data(
JournalFile *f,
assert(f);
assert(o);
assert(n > 0);
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
m = journal_file_entry_array_n_items(o);
if (q <= last) {
return -EBADMSG;
last = q;
a = next;
static int verify_hash_table(
JournalFile *f,
uint64_t i, n;
assert(f);
Object *o;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
last = p;
p = next;
return -EBADMSG;
uint64_t n, h, q;
assert(f);
h = hash % n;
Object *o;
static int verify_entry(
JournalFile *f,
uint64_t i, n;
assert(f);
assert(o);
n = journal_file_entry_n_items(o);
uint64_t q, h;
Object *u;
return -EBADMSG;
return -EBADMSG;
r = data_object_in_hash_table(f, h, q);
return -EBADMSG;
static int verify_entry_array(
JournalFile *f,
assert(f);
Object *o;
return -EBADMSG;
return -EBADMSG;
return -EBADMSG;
m = journal_file_entry_array_n_items(o);
uint64_t p;
if (p <= last) {
return -EBADMSG;
last = p;
return -EBADMSG;
a = next;
Object *o;
uint64_t p = 0;
bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0;
assert(f);
if (data_fd < 0) {
goto fail;
if (entry_fd < 0) {
goto fail;
if (entry_array_fd < 0) {
goto fail;
r = journal_file_hmac_put_header(f);
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
n_objects ++;
r = journal_file_object_verify(f, o);
goto fail;
r = -EBADMSG;
goto fail;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
goto fail;
if (!entry_seqnum_set &&
r = -EBADMSG;
goto fail;
if (entry_seqnum_set &&
r = -EBADMSG;
goto fail;
entry_seqnum_set = true;
if (entry_monotonic_set &&
r = -EBADMSG;
goto fail;
entry_monotonic_set = true;
if (!entry_realtime_set &&
r = -EBADMSG;
goto fail;
entry_realtime_set = true;
n_entries ++;
goto fail;
if (found_main_entry_array) {
r = -EBADMSG;
goto fail;
found_main_entry_array = true;
goto fail;
n_data++;
n_fields++;
r = -EBADMSG;
goto fail;
le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
r = -EBADMSG;
goto fail;
n_weird ++;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
if (!found_main_entry_array) {
r = -EBADMSG;
goto fail;
if (entry_seqnum_set &&
r = -EBADMSG;
goto fail;
if (entry_monotonic_set &&
r = -EBADMSG;
goto fail;
r = -EBADMSG;
goto fail;
r = verify_entry_array(f,
&last_usec);
goto fail;
r = verify_hash_table(f,
&last_usec);
goto fail;
fail:
f->path,
if (data_fd >= 0) {
if (entry_fd >= 0) {
if (entry_array_fd >= 0) {