]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/test-journal-verify.c
Properly check for overflow in offsets
[thirdparty/systemd.git] / src / journal / test-journal-verify.c
CommitLineData
0284adc6
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <unistd.h>
24#include <fcntl.h>
25
26#include "util.h"
27#include "log.h"
28#include "journal-file.h"
29#include "journal-verify.h"
b72631e5 30#include "journal-authenticate.h"
0284adc6
LP
31
32#define N_ENTRIES 6000
33#define RANDOM_RANGE 77
34
b72631e5
LP
35static void bit_toggle(const char *fn, uint64_t p) {
36 uint8_t b;
37 ssize_t r;
38 int fd;
39
40 fd = open(fn, O_RDWR|O_CLOEXEC);
41 assert(fd >= 0);
42
43 r = pread(fd, &b, 1, p/8);
44 assert(r == 1);
45
46 b ^= 1 << (p % 8);
47
48 r = pwrite(fd, &b, 1, p/8);
49 assert(r == 1);
50
51 close_nointr_nofail(fd);
52}
53
54static int raw_verify(const char *fn, const char *verification_key) {
55 JournalFile *f;
56 int r;
57
feb12d3e 58 r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
b72631e5
LP
59 if (r < 0)
60 return r;
61
62 r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
63 journal_file_close(f);
64
65 return r;
66}
67
0284adc6
LP
68int main(int argc, char *argv[]) {
69 char t[] = "/tmp/journal-XXXXXX";
70 unsigned n;
71 JournalFile *f;
14d10188 72 const char *verification_key = argv[1];
b72631e5 73 usec_t from = 0, to = 0, total = 0;
6c7be122
LP
74 char a[FORMAT_TIMESTAMP_MAX];
75 char b[FORMAT_TIMESTAMP_MAX];
76 char c[FORMAT_TIMESPAN_MAX];
b72631e5
LP
77 struct stat st;
78 uint64_t p;
0284adc6
LP
79
80 log_set_max_level(LOG_DEBUG);
81
82 assert_se(mkdtemp(t));
83 assert_se(chdir(t) >= 0);
84
85 log_info("Generating...");
86
14d10188 87 assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
0284adc6
LP
88
89 for (n = 0; n < N_ENTRIES; n++) {
90 struct iovec iovec;
91 struct dual_timestamp ts;
92 char *test;
93
94 dual_timestamp_get(&ts);
95
96 assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE));
97
98 iovec.iov_base = (void*) test;
99 iovec.iov_len = strlen(test);
100
101 assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
102
103 free(test);
104 }
105
106 journal_file_close(f);
107
108 log_info("Verifying...");
109
feb12d3e 110 assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
f7fab8a5
LP
111 /* journal_file_print_header(f); */
112 journal_file_dump(f);
3223f44f 113
b72631e5 114 assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
6c7be122 115
feb12d3e 116 if (verification_key && JOURNAL_HEADER_SEALED(f->header)) {
b72631e5
LP
117 log_info("=> Validated from %s to %s, %s missing",
118 format_timestamp(a, sizeof(a), from),
119 format_timestamp(b, sizeof(b), to),
2fa4092c 120 format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
b72631e5 121 }
feb12d3e 122
0284adc6
LP
123 journal_file_close(f);
124
f7fab8a5
LP
125 if (verification_key) {
126 log_info("Toggling bits...");
b72631e5 127
f7fab8a5 128 assert_se(stat("test.journal", &st) >= 0);
b72631e5 129
f7fab8a5
LP
130 for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
131 bit_toggle("test.journal", p);
b72631e5 132
f7fab8a5 133 log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8);
b72631e5 134
f7fab8a5
LP
135 if (raw_verify("test.journal", verification_key) >= 0)
136 log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %llu (bit %llu) can be toggled without detection." ANSI_HIGHLIGHT_OFF, (unsigned long long) p / 8, (unsigned long long) p % 8);
b72631e5 137
f7fab8a5
LP
138 bit_toggle("test.journal", p);
139 }
b72631e5
LP
140 }
141
0284adc6
LP
142 log_info("Exiting...");
143
144 assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
145
146 return 0;
147}