[systemd-commits] 12 commits - TODO src/journal
Lennart Poettering
lennart at kemper.freedesktop.org
Mon Aug 20 07:12:56 PDT 2012
TODO | 2
src/journal/fsprg.c | 2
src/journal/journal-authenticate.c | 2
src/journal/journal-def.h | 9 +
src/journal/journal-file.c | 60 +++++++---
src/journal/journal-file.h | 23 +++
src/journal/journal-verify.c | 218 ++++++++++++++++++++++++++-----------
src/journal/journal-verify.h | 2
src/journal/journalctl.c | 20 ++-
src/journal/journald.c | 2
src/journal/mmap-cache.c | 55 +++++++--
src/journal/mmap-cache.h | 2
src/journal/sd-journal.c | 5
src/journal/test-journal-verify.c | 72 ++++++++++--
14 files changed, 356 insertions(+), 118 deletions(-)
New commits:
commit 8088cbd3cfcf539c984d8042cd2b92ebbfda6d82
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Aug 20 16:11:42 2012 +0200
journal: use a macro to check for file header flags
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index 9853edb..ddcf856 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -464,5 +464,5 @@ int journal_file_append_first_tag(JournalFile *f) {
bool journal_file_fss_enabled(JournalFile *f) {
assert(f);
- return !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
+ return JOURNAL_HEADER_SEALED(f->header);
}
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index f419cf6..760efae 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -210,8 +210,7 @@ static int journal_file_verify_header(JournalFile *f) {
if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
return -EBADMSG;
- if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED) &&
- !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
+ if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
return -EBADMSG;
if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
@@ -251,10 +250,10 @@ static int journal_file_verify_header(JournalFile *f) {
}
}
- f->compress = !!(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED);
+ f->compress = JOURNAL_HEADER_COMPRESSED(f->header);
if (f->writable)
- f->seal = !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
+ f->seal = JOURNAL_HEADER_SEALED(f->header);
return 0;
}
@@ -1927,10 +1926,10 @@ void journal_file_print_header(JournalFile *f) {
f->header->state == STATE_OFFLINE ? "OFFLINE" :
f->header->state == STATE_ONLINE ? "ONLINE" :
f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
- (f->header->compatible_flags & HEADER_COMPATIBLE_SEALED) ? " SEALED" : "",
- (f->header->compatible_flags & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
- (f->header->incompatible_flags & HEADER_INCOMPATIBLE_COMPRESSED) ? " COMPRESSED" : "",
- (f->header->incompatible_flags & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
+ JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "",
+ (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
+ JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "",
+ (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
(unsigned long long) le64toh(f->header->header_size),
(unsigned long long) le64toh(f->header->arena_size),
(unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 7358173..5b1530e 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -137,6 +137,12 @@ static inline bool VALID_EPOCH(uint64_t u) {
#define JOURNAL_HEADER_CONTAINS(h, field) \
(le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
+#define JOURNAL_HEADER_SEALED(h) \
+ (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED))
+
+#define JOURNAL_HEADER_COMPRESSED(h) \
+ (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED))
+
int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
uint64_t journal_file_entry_n_items(Object *o);
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 08f3e16..6afeab9 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -36,7 +36,6 @@
/* FIXME:
*
* - evolve key even if nothing happened in regular intervals
- * - add macro for accessing flags
*
* - Allow building without libgcrypt
* - check with sparse
@@ -806,8 +805,7 @@ int journal_file_verify(
goto fail;
}
- if (o->object.flags & OBJECT_COMPRESSED &&
- !(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED)) {
+ if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) {
log_error("Compressed object in file without compression at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
@@ -828,7 +826,7 @@ int journal_file_verify(
break;
case OBJECT_ENTRY:
- if ((le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED) && n_tags <= 0) {
+ if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) {
log_error("First entry before first tag at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
@@ -941,7 +939,7 @@ int journal_file_verify(
case OBJECT_TAG: {
uint64_t q, rt;
- if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED)) {
+ if (!JOURNAL_HEADER_SEALED(f->header)) {
log_error("Tag object in file without sealing at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
commit f7fab8a5ae7a3b378040203821383f5a8fc91126
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Aug 20 15:59:33 2012 +0200
journal: fix tag ordering check
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index c6b25ce..f419cf6 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1855,7 +1855,7 @@ void journal_file_dump(JournalFile *f) {
break;
case OBJECT_ENTRY:
- printf("Type: OBJECT_ENTRY %llu %llu %llu\n",
+ printf("Type: OBJECT_ENTRY seqnum=%llu monotonic=%llu realtime=%llu\n",
(unsigned long long) le64toh(o->entry.seqnum),
(unsigned long long) le64toh(o->entry.monotonic),
(unsigned long long) le64toh(o->entry.realtime));
@@ -1874,8 +1874,9 @@ void journal_file_dump(JournalFile *f) {
break;
case OBJECT_TAG:
- printf("Type: OBJECT_TAG %llu\n",
- (unsigned long long) le64toh(o->tag.seqnum));
+ printf("Type: OBJECT_TAG seqnum=%llu epoch=%llu\n",
+ (unsigned long long) le64toh(o->tag.seqnum),
+ (unsigned long long) le64toh(o->tag.epoch));
break;
}
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index e3c3ccd..08f3e16 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -709,7 +709,7 @@ int journal_file_verify(
bool show_progress) {
int r;
Object *o;
- uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0;
+ uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0, last_sealed_realtime = 0;
uint64_t entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0;
sd_id128_t entry_boot_id;
bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
@@ -838,7 +838,7 @@ int journal_file_verify(
if (r < 0)
goto fail;
- if (last_tag_realtime > le64toh(o->entry.realtime)) {
+ if (le64toh(o->entry.realtime) < last_tag_realtime) {
log_error("Older entry after newer tag at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
@@ -962,8 +962,8 @@ int journal_file_verify(
if (f->seal) {
log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
- rt = (o->tag.epoch + 1) * f->fss_interval_usec + f->fss_start_usec;
- if (entry_realtime_set && entry_realtime >= rt) {
+ rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
+ if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
r = -EBADMSG;
goto fail;
@@ -1014,6 +1014,7 @@ int journal_file_verify(
f->hmac_running = false;
last_tag_realtime = rt;
+ last_sealed_realtime = entry_realtime;
}
last_tag = p + ALIGN64(le64toh(o->object.size));
@@ -1158,7 +1159,7 @@ int journal_file_verify(
if (first_validated)
*first_validated = last_tag_realtime ? le64toh(f->header->head_entry_realtime) : 0;
if (last_validated)
- *last_validated = last_tag_realtime;
+ *last_validated = last_sealed_realtime;
if (last_contained)
*last_contained = le64toh(f->header->tail_entry_realtime);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index ba678a2..e61ddf6 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -478,7 +478,7 @@ static int setup_keys(void) {
return log_oom();
if (access(p, F_OK) >= 0) {
- log_error("Evolving key file %s exists already.", p);
+ log_error("Sealing key file %s exists already.", p);
r = -EEXIST;
goto finish;
}
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
index 4e6c119..ed6e21d 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/journal/test-journal-verify.c
@@ -108,7 +108,8 @@ int main(int argc, char *argv[]) {
log_info("Verifying...");
assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, true, NULL, NULL, NULL, &f) == 0);
- journal_file_print_header(f);
+ /* journal_file_print_header(f); */
+ journal_file_dump(f);
assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
@@ -120,21 +121,21 @@ int main(int argc, char *argv[]) {
}
journal_file_close(f);
- log_info("Toggling bits...");
+ if (verification_key) {
+ log_info("Toggling bits...");
- assert_se(stat("test.journal", &st) >= 0);
+ assert_se(stat("test.journal", &st) >= 0);
- for (p = 240*8; p < ((uint64_t) st.st_size * 8); p ++) {
- bit_toggle("test.journal", p);
+ for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) {
+ bit_toggle("test.journal", p);
- log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8);
+ log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8);
- if (raw_verify("test.journal", verification_key) >= 0) {
- 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);
- sleep(1);
- }
+ if (raw_verify("test.journal", verification_key) >= 0)
+ 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);
- bit_toggle("test.journal", p);
+ bit_toggle("test.journal", p);
+ }
}
log_info("Exiting...");
commit a2e99cdf94a8a0350ff13b241de07f34c015b1fc
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Aug 19 15:16:32 2012 +0200
journal: fix bisection algorithm
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 535b272..e3c3ccd 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -266,10 +266,14 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
if (*z == p)
return 1;
+ if (a + 1 >= b)
+ return 0;
+
if (p < *z)
b = c;
- else
+ else {
a = c;
+ }
}
return 0;
commit fc89a13992384ab8d8fb0c937b021434123bbc49
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Aug 19 15:15:59 2012 +0200
journal: validate timestamps as well
diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c
index 34ce3be..2190b7c 100644
--- a/src/journal/fsprg.c
+++ b/src/journal/fsprg.c
@@ -160,7 +160,7 @@ static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) {
gcry_mpi_sub_ui(phi, p, 1);
/* count number of used bits in m */
- for (n = 0; ((uint64_t)1 << n) <= m; n++)
+ for (n = 0; (1ULL << n) <= m; n++)
;
r = gcry_mpi_new(0);
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index e2ef033..7358173 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -119,6 +119,21 @@ int journal_file_open_reliably(
#define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
#define VALID64(x) (((x) & 7ULL) == 0ULL)
+static inline bool VALID_REALTIME(uint64_t u) {
+ /* This considers timestamps until the year 3112 valid. That should be plenty room... */
+ return u > 0 && u < (1ULL << 55);
+}
+
+static inline bool VALID_MONOTONIC(uint64_t u) {
+ /* This considers timestamps until 1142 years of runtime valid. */
+ return u < (1ULL << 55);
+}
+
+static inline bool VALID_EPOCH(uint64_t u) {
+ /* This allows changing the key for 1142 years, every usec. */
+ return u < (1ULL << 55);
+}
+
#define JOURNAL_HEADER_CONTAINS(h, field) \
(le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index a318176..535b272 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -35,8 +35,8 @@
/* FIXME:
*
- * - write bit mucking test
* - evolve key even if nothing happened in regular intervals
+ * - add macro for accessing flags
*
* - Allow building without libgcrypt
* - check with sparse
@@ -115,7 +115,8 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
return -EBADMSG;
if (le64toh(o->entry.seqnum) <= 0 ||
- le64toh(o->entry.realtime) <= 0)
+ !VALID_REALTIME(le64toh(o->entry.realtime)) ||
+ !VALID_MONOTONIC(le64toh(o->entry.monotonic)))
return -EBADMSG;
for (i = 0; i < journal_file_entry_n_items(o); i++) {
@@ -169,6 +170,10 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
case OBJECT_TAG:
if (le64toh(o->object.size) != sizeof(TagObject))
return -EBADMSG;
+
+ if (!VALID_EPOCH(o->tag.epoch))
+ return -EBADMSG;
+
break;
}
commit 84168d8068bb67dcd5468ab3b376535d81643aef
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 01:46:20 2012 +0200
mmap: resize arrays dynamically
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index df991a4..c6b25ce 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2003,10 +2003,7 @@ int journal_file_open(
if (mmap_cache)
f->mmap = mmap_cache_ref(mmap_cache);
else {
- /* One context for each type, plus the zeroth catchall
- * context. One fd for the file plus one for each type
- * (which we need during verification */
- f->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, 1 + _OBJECT_TYPE_MAX);
+ f->mmap = mmap_cache_new();
if (!f->mmap) {
r = -ENOMEM;
goto fail;
diff --git a/src/journal/journald.c b/src/journal/journald.c
index d431953..f74c461 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -2794,7 +2794,7 @@ static int server_init(Server *s) {
if (!s->user_journals)
return log_oom();
- s->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, USER_JOURNALS_MAX + 2);
+ s->mmap = mmap_cache_new();
if (!s->mmap)
return log_oom();
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index 9782139..69efb20 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -30,7 +30,10 @@
#include "mmap-cache.h"
#define WINDOW_SIZE (8ULL*1024ULL*1024ULL)
-#define WINDOWS_MAX 32
+
+#define DEFAULT_WINDOWS_MAX 64
+#define DEFAULT_FDS_MAX 32
+#define DEFAULT_CONTEXTS_MAX 32
typedef struct Window {
int fd;
@@ -236,19 +239,16 @@ static void mmap_cache_free(MMapCache *m) {
free(m);
}
-MMapCache* mmap_cache_new(unsigned contexts_max, unsigned fds_max) {
+MMapCache* mmap_cache_new(void) {
MMapCache *m;
- assert(contexts_max > 0);
- assert(fds_max > 0);
-
m = new0(MMapCache, 1);
if (!m)
return NULL;
- m->contexts_max = contexts_max;
- m->fds_max = fds_max;
- m->windows_max = MAX(m->contexts_max, WINDOWS_MAX);
+ m->contexts_max = DEFAULT_CONTEXTS_MAX;
+ m->fds_max = DEFAULT_FDS_MAX;
+ m->windows_max = DEFAULT_WINDOWS_MAX;
m->n_ref = 1;
m->lru_first = (unsigned) -1;
m->lru_last = (unsigned) -1;
@@ -465,8 +465,18 @@ static int mmap_cache_get_fd_index(MMapCache *m, int fd, unsigned *fd_index) {
if (r != 0)
return r;
- if (m->n_fds >= m->fds_max)
- return -E2BIG;
+ if (m->n_fds >= m->fds_max) {
+ unsigned k;
+ FileDescriptor *n;
+
+ k = m->n_fds * 2;
+ n = realloc(m->by_fd, sizeof(FileDescriptor) * k);
+ if (!n)
+ return -ENOMEM;
+
+ m->fds_max = k;
+ m->by_fd = n;
+ }
j = m->by_fd + m->n_fds ++;
j->fd = fd;
@@ -580,10 +590,33 @@ int mmap_cache_get(
assert(m);
assert(fd >= 0);
- assert(context < m->contexts_max);
assert(size > 0);
assert(ret);
+ if (context >= m->contexts_max) {
+ unsigned k, *n;
+ Window *w;
+
+ /* Increase the number of contexts if necessary, and
+ * make sure we have twice the number of windows */
+
+ k = context * 2;
+ n = realloc(m->by_context, sizeof(unsigned) * k);
+ if (!n)
+ return -ENOMEM;
+ memset(n + m->contexts_max, -1, (k - m->contexts_max) * sizeof(unsigned));
+ m->contexts_max = k;
+ m->by_context = n;
+
+ k = MAX(m->windows_max, m->contexts_max*2);
+ w = realloc(m->windows, sizeof(Window) * k);
+ if (!w)
+ return -ENOMEM;
+
+ m->windows_max = k;
+ m->windows = w;
+ }
+
/* Maybe the current pointer for this context is already the
* right one? */
r = mmap_cache_current(m, fd, context, offset, size, ret);
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
index 984b759..aae4544 100644
--- a/src/journal/mmap-cache.h
+++ b/src/journal/mmap-cache.h
@@ -25,7 +25,7 @@
typedef struct MMapCache MMapCache;
-MMapCache* mmap_cache_new(unsigned contexts_max, unsigned fds_max);
+MMapCache* mmap_cache_new(void);
MMapCache* mmap_cache_ref(MMapCache *m);
MMapCache* mmap_cache_unref(MMapCache *m);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 41526b3..725c979 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -1439,10 +1439,7 @@ static sd_journal *journal_new(int flags, const char *path) {
return NULL;
}
- /* One context for each type, plus the zeroth catchall
- * context. One fd for each file plus one for each type, which
- * is need when verifying things */
- j->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, JOURNAL_FILES_MAX + _OBJECT_TYPE_MAX);
+ j->mmap = mmap_cache_new();
if (!j->mmap) {
hashmap_free(j->files);
hashmap_free(j->directories_by_path);
commit fb9a24b6b1ed5b1f42e6e350ccdb7e11800a83bd
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 01:45:39 2012 +0200
journal: even more simple static object tests
diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
index 45c3cde..8f00176 100644
--- a/src/journal/journal-def.h
+++ b/src/journal/journal-def.h
@@ -188,6 +188,8 @@ _packed_ struct Header {
/* Added in 189 */
le64_t n_tags;
le64_t n_entry_arrays;
+
+ /* Size: 224 */
};
#define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index e04ffd0..df991a4 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -798,6 +798,14 @@ uint64_t journal_file_entry_array_n_items(Object *o) {
return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t);
}
+uint64_t journal_file_hash_table_n_items(Object *o) {
+ assert(o);
+ assert(o->object.type == OBJECT_DATA_HASH_TABLE ||
+ o->object.type == OBJECT_FIELD_HASH_TABLE);
+
+ return (le64toh(o->object.size) - offsetof(Object, hash_table.items)) / sizeof(HashItem);
+}
+
static int link_entry_into_array(JournalFile *f,
le64_t *first,
le64_t *idx,
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 2d2bf31..e2ef033 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -126,6 +126,7 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
uint64_t journal_file_entry_n_items(Object *o);
uint64_t journal_file_entry_array_n_items(Object *o);
+uint64_t journal_file_hash_table_n_items(Object *o);
int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset);
int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset);
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index e3bd8ff..a318176 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -134,6 +134,19 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0)
return -EBADMSG;
+ for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
+ if (o->hash_table.items[i].head_hash_offset != 0 &&
+ !VALID64(le64toh(o->hash_table.items[i].head_hash_offset)))
+ return -EBADMSG;
+ if (o->hash_table.items[i].tail_hash_offset != 0 &&
+ !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset)))
+ return -EBADMSG;
+
+ if ((o->hash_table.items[i].head_hash_offset != 0) !=
+ (o->hash_table.items[i].tail_hash_offset != 0))
+ return -EBADMSG;
+ }
+
break;
case OBJECT_ENTRY_ARRAY:
@@ -146,6 +159,11 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
if (!VALID64(o->entry_array.next_entry_array_offset))
return -EBADMSG;
+ for (i = 0; i < journal_file_entry_array_n_items(o); i++)
+ if (o->entry_array.items[i] != 0 &&
+ !VALID64(o->entry_array.items[i]))
+ return -EBADMSG;
+
break;
case OBJECT_TAG:
commit 97147f8c1f63234470a7062d2ed0f999c0996d42
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 00:40:48 2012 +0200
journal: refuse verification of files with unknown flags
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index f66b235..e3bd8ff 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -692,6 +692,8 @@ int journal_file_verify(
char data_path[] = "/var/tmp/journal-data-XXXXXX",
entry_path[] = "/var/tmp/journal-entry-XXXXXX",
entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX";
+ unsigned i;
+ bool found_last;
assert(f);
@@ -728,6 +730,24 @@ int journal_file_verify(
}
unlink(entry_array_path);
+#ifdef HAVE_GCRYPT
+ if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
+#else
+ if (f->header->compatible_flags != 0)
+#endif
+ {
+ log_error("Cannot verify file with unknown extensions.");
+ r = -ENOTSUP;
+ goto fail;
+ }
+
+ for (i = 0; i < sizeof(f->header->reserved); i++)
+ if (f->header->reserved[i] != 0) {
+ log_error("Reserved field in non-zero.");
+ r = -EBADMSG;
+ goto fail;
+ }
+
/* First iteration: we go through all objects, verify the
* superficial structure, headers, hashes. */
@@ -742,12 +762,15 @@ int journal_file_verify(
goto fail;
}
- if (le64toh(f->header->tail_object_offset) < p) {
+ if (p > le64toh(f->header->tail_object_offset)) {
log_error("Invalid tail object pointer");
r = -EBADMSG;
goto fail;
}
+ if (p == le64toh(f->header->tail_object_offset))
+ found_last = true;
+
n_objects ++;
r = journal_file_object_verify(f, o);
@@ -983,6 +1006,12 @@ int journal_file_verify(
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;
commit b72631e59c1b9f62bcfaf1ce3f7e72e4a3beee89
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 00:40:03 2012 +0200
jounral: write bit fiddling test
This test goes through every single bit in a journal file, toggles it,
and checks if this change is detected by the verification.
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 39cf3a3..f66b235 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -394,7 +394,8 @@ static int verify_hash_table(
int data_fd, uint64_t n_data,
int entry_fd, uint64_t n_entries,
int entry_array_fd, uint64_t n_entry_arrays,
- usec_t *last_usec) {
+ usec_t *last_usec,
+ bool show_progress) {
uint64_t i, n;
int r;
@@ -409,7 +410,8 @@ static int verify_hash_table(
for (i = 0; i < n; i++) {
uint64_t last = 0, p;
- draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
+ if (show_progress)
+ draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
p = le64toh(f->data_hash_table[i].head_hash_offset);
while (p != 0) {
@@ -535,7 +537,8 @@ static int verify_entry_array(
int data_fd, uint64_t n_data,
int entry_fd, uint64_t n_entries,
int entry_array_fd, uint64_t n_entry_arrays,
- usec_t *last_usec) {
+ usec_t *last_usec,
+ bool show_progress) {
uint64_t i = 0, a, n, last = 0;
int r;
@@ -552,7 +555,8 @@ static int verify_entry_array(
uint64_t next, m, j;
Object *o;
- draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
+ if (show_progress)
+ draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
if (a == 0) {
log_error("Array chain too short at %llu of %llu",
@@ -674,7 +678,8 @@ static int journal_file_parse_verification_key(JournalFile *f, const char *key)
int journal_file_verify(
JournalFile *f,
const char *key,
- usec_t *first_validated, usec_t *last_validated, usec_t *last_contained) {
+ usec_t *first_validated, usec_t *last_validated, usec_t *last_contained,
+ bool show_progress) {
int r;
Object *o;
uint64_t p = 0, last_tag = 0, last_epoch = 0, last_tag_realtime = 0;
@@ -728,7 +733,8 @@ int journal_file_verify(
p = le64toh(f->header->header_size);
while (p != 0) {
- draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
+ if (show_progress)
+ draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
r = journal_file_move_to_object(f, -1, p, &o);
if (r < 0) {
@@ -891,8 +897,6 @@ int journal_file_verify(
goto fail;
}
- log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
-
if (le64toh(o->tag.seqnum) != n_tags + 1) {
log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p);
r = -EBADMSG;
@@ -1070,7 +1074,8 @@ int journal_file_verify(
data_fd, n_data,
entry_fd, n_entries,
entry_array_fd, n_entry_arrays,
- &last_usec);
+ &last_usec,
+ show_progress);
if (r < 0)
goto fail;
@@ -1078,11 +1083,13 @@ int journal_file_verify(
data_fd, n_data,
entry_fd, n_entries,
entry_array_fd, n_entry_arrays,
- &last_usec);
+ &last_usec,
+ show_progress);
if (r < 0)
goto fail;
- flush_progress();
+ if (show_progress)
+ flush_progress();
mmap_cache_close_fd(f->mmap, data_fd);
mmap_cache_close_fd(f->mmap, entry_fd);
@@ -1102,7 +1109,8 @@ int journal_file_verify(
return 0;
fail:
- flush_progress();
+ if (show_progress)
+ flush_progress();
log_error("File corruption detected at %s:%llu (of %llu, %llu%%).",
f->path,
diff --git a/src/journal/journal-verify.h b/src/journal/journal-verify.h
index e4449c6..a4633ad 100644
--- a/src/journal/journal-verify.h
+++ b/src/journal/journal-verify.h
@@ -23,4 +23,4 @@
#include "journal-file.h"
-int journal_file_verify(JournalFile *f, const char *key, usec_t *first_validated, usec_t *last_validated, usec_t *last_contained);
+int journal_file_verify(JournalFile *f, const char *key, usec_t *first_validated, usec_t *last_validated, usec_t *last_contained, bool show_progress);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 25f41f6..ba678a2 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -637,7 +637,7 @@ static int verify(sd_journal *j) {
log_warning("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
#endif
- k = journal_file_verify(f, arg_verify_key, &from, &to, &total);
+ k = journal_file_verify(f, arg_verify_key, &from, &to, &total, true);
if (k == -EINVAL) {
/* If the key was invalid give up right-away. */
return k;
@@ -648,7 +648,7 @@ static int verify(sd_journal *j) {
char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
log_info("PASS: %s", f->path);
- if (journal_file_fss_enabled(f))
+ if (arg_verify_key && journal_file_fss_enabled(f))
log_info("=> Validated from %s to %s, %s missing",
format_timestamp(a, sizeof(a), from),
format_timestamp(b, sizeof(b), to),
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
index df0a5dd..4e6c119 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/journal/test-journal-verify.c
@@ -27,19 +27,55 @@
#include "log.h"
#include "journal-file.h"
#include "journal-verify.h"
+#include "journal-authenticate.h"
#define N_ENTRIES 6000
#define RANDOM_RANGE 77
+static void bit_toggle(const char *fn, uint64_t p) {
+ uint8_t b;
+ ssize_t r;
+ int fd;
+
+ fd = open(fn, O_RDWR|O_CLOEXEC);
+ assert(fd >= 0);
+
+ r = pread(fd, &b, 1, p/8);
+ assert(r == 1);
+
+ b ^= 1 << (p % 8);
+
+ r = pwrite(fd, &b, 1, p/8);
+ assert(r == 1);
+
+ close_nointr_nofail(fd);
+}
+
+static int raw_verify(const char *fn, const char *verification_key) {
+ JournalFile *f;
+ int r;
+
+ r = journal_file_open(fn, O_RDONLY, 0666, true, true, NULL, NULL, NULL, &f);
+ if (r < 0)
+ return r;
+
+ r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
+ journal_file_close(f);
+
+ return r;
+}
+
int main(int argc, char *argv[]) {
char t[] = "/tmp/journal-XXXXXX";
unsigned n;
JournalFile *f;
const char *verification_key = argv[1];
- usec_t from, to, total;
+ usec_t from = 0, to = 0, total = 0;
char a[FORMAT_TIMESTAMP_MAX];
char b[FORMAT_TIMESTAMP_MAX];
char c[FORMAT_TIMESPAN_MAX];
+ struct stat st;
+ uint64_t p;
log_set_max_level(LOG_DEBUG);
@@ -71,19 +107,36 @@ int main(int argc, char *argv[]) {
log_info("Verifying...");
- assert_se(journal_file_open("test.journal", O_RDONLY, 0666, false, false, NULL, NULL, NULL, &f) == 0);
-
+ assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, true, NULL, NULL, NULL, &f) == 0);
journal_file_print_header(f);
- assert_se(journal_file_verify(f, verification_key, &from, &to, &total) >= 0);
-
- log_info("=> Validated from %s to %s, %s missing",
- format_timestamp(a, sizeof(a), from),
- format_timestamp(b, sizeof(b), to),
- format_timespan(c, sizeof(c), total > to ? total - to : 0));
+ assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0);
+ if (verification_key && journal_file_fss_enabled(f)) {
+ log_info("=> Validated from %s to %s, %s missing",
+ format_timestamp(a, sizeof(a), from),
+ format_timestamp(b, sizeof(b), to),
+ format_timespan(c, sizeof(c), total > to ? total - to : 0));
+ }
journal_file_close(f);
+ log_info("Toggling bits...");
+
+ assert_se(stat("test.journal", &st) >= 0);
+
+ for (p = 240*8; p < ((uint64_t) st.st_size * 8); p ++) {
+ bit_toggle("test.journal", p);
+
+ log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8);
+
+ if (raw_verify("test.journal", verification_key) >= 0) {
+ 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);
+ sleep(1);
+ }
+
+ bit_toggle("test.journal", p);
+ }
+
log_info("Exiting...");
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
commit c586dbf110abdbf0317bdd0f0a5900d709194409
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 00:38:57 2012 +0200
journal: fix verification without key
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 3cf28a7..e04ffd0 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -65,7 +65,7 @@ void journal_file_close(JournalFile *f) {
assert(f);
/* Write the final tag */
- if (f->seal)
+ if (f->seal && f->writable)
journal_file_append_tag(f);
/* Sync everything to disk, before we mark the file offline */
@@ -252,7 +252,9 @@ static int journal_file_verify_header(JournalFile *f) {
}
f->compress = !!(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED);
- f->seal = !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
+
+ if (f->writable)
+ f->seal = !!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_SEALED);
return 0;
}
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 7be0d2e..39cf3a3 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -696,7 +696,8 @@ int journal_file_verify(
log_error("Failed to parse seed.");
return r;
}
- }
+ } else if (f->seal)
+ return -ENOKEY;
data_fd = mkostemp(data_path, O_CLOEXEC);
if (data_fd < 0) {
@@ -904,60 +905,65 @@ int journal_file_verify(
goto fail;
}
- rt = (o->tag.epoch + 1) * f->fss_interval_usec + f->fss_start_usec;
- if (entry_realtime_set && entry_realtime >= rt) {
- log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
- r = -EBADMSG;
- goto fail;
- }
-
- /* OK, now we know the epoch. So let's now set
- * it, and calculate the HMAC for everything
- * since the last tag. */
- r = journal_file_fsprg_seek(f, le64toh(o->tag.epoch));
- if (r < 0)
- goto fail;
+ if (f->seal) {
+ log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum));
- r = journal_file_hmac_start(f);
- if (r < 0)
- goto fail;
+ rt = (o->tag.epoch + 1) * f->fss_interval_usec + f->fss_start_usec;
+ if (entry_realtime_set && entry_realtime >= rt) {
+ log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p);
+ r = -EBADMSG;
+ goto fail;
+ }
- if (last_tag == 0) {
- r = journal_file_hmac_put_header(f);
+ /* OK, now we know the epoch. So let's now set
+ * it, and calculate the HMAC for everything
+ * since the last tag. */
+ r = journal_file_fsprg_seek(f, le64toh(o->tag.epoch));
if (r < 0)
goto fail;
- q = le64toh(f->header->header_size);
- } else
- q = last_tag;
-
- while (q <= p) {
- r = journal_file_move_to_object(f, -1, q, &o);
+ r = journal_file_hmac_start(f);
if (r < 0)
goto fail;
- r = journal_file_hmac_put_object(f, -1, q);
+ if (last_tag == 0) {
+ r = journal_file_hmac_put_header(f);
+ if (r < 0)
+ goto fail;
+
+ q = le64toh(f->header->header_size);
+ } else
+ q = last_tag;
+
+ while (q <= p) {
+ r = journal_file_move_to_object(f, -1, q, &o);
+ if (r < 0)
+ goto fail;
+
+ r = journal_file_hmac_put_object(f, -1, q);
+ if (r < 0)
+ goto fail;
+
+ q = q + ALIGN64(le64toh(o->object.size));
+ }
+
+ /* Position might have changed, let's reposition things */
+ r = journal_file_move_to_object(f, -1, p, &o);
if (r < 0)
goto fail;
- q = q + ALIGN64(le64toh(o->object.size));
- }
-
- /* Position might have changed, let's reposition things */
- r = journal_file_move_to_object(f, -1, p, &o);
- if (r < 0)
- goto fail;
+ if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
+ log_error("Tag failed verification at %llu", (unsigned long long) p);
+ r = -EBADMSG;
+ goto fail;
+ }
- if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
- log_error("Tag failed verification at %llu", (unsigned long long) p);
- r = -EBADMSG;
- goto fail;
+ f->hmac_running = false;
+ last_tag_realtime = rt;
}
- f->hmac_running = false;
-
last_tag = p + ALIGN64(le64toh(o->object.size));
- last_tag_realtime = rt;
+ last_epoch = le64toh(o->tag.epoch);
n_tags ++;
break;
@@ -1087,7 +1093,7 @@ int journal_file_verify(
close_nointr_nofail(entry_array_fd);
if (first_validated)
- *first_validated = le64toh(f->header->head_entry_realtime);
+ *first_validated = last_tag_realtime ? le64toh(f->header->head_entry_realtime) : 0;
if (last_validated)
*last_validated = last_tag_realtime;
if (last_contained)
commit db11ac1ab56bc13514a029e7d126c5efe2c68bc2
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Aug 18 00:37:21 2012 +0200
journald: add additional simple static tests to verifier
diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
index 52c55ab..45c3cde 100644
--- a/src/journal/journal-def.h
+++ b/src/journal/journal-def.h
@@ -140,9 +140,10 @@ union Object {
};
enum {
- STATE_OFFLINE,
- STATE_ONLINE,
- STATE_ARCHIVED
+ STATE_OFFLINE = 0,
+ STATE_ONLINE = 1,
+ STATE_ARCHIVED = 2,
+ _STATE_MAX
};
/* Header flags */
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 08d4285..3cf28a7 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -203,6 +203,9 @@ static int journal_file_verify_header(JournalFile *f) {
#endif
}
+ if (f->header->state >= _STATE_MAX)
+ return -EBADMSG;
+
/* The first addition was n_data, so check that we are at least this large */
if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
return -EBADMSG;
@@ -211,7 +214,16 @@ static int journal_file_verify_header(JournalFile *f) {
!JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
return -EBADMSG;
- if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
+ if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
+ return -ENODATA;
+
+ if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
+ return -ENODATA;
+
+ if (!VALID64(f->header->data_hash_table_offset) ||
+ !VALID64(f->header->field_hash_table_offset) ||
+ !VALID64(f->header->tail_object_offset) ||
+ !VALID64(f->header->entry_array_offset))
return -ENODATA;
if (f->writable) {
@@ -351,6 +363,10 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
assert(f);
assert(ret);
+ /* Objects may only be located at multiple of 64 bit */
+ if (!VALID64(offset))
+ return -EFAULT;
+
/* One context for each type, plus one catch-all for the rest */
context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 58de214..2d2bf31 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -117,6 +117,7 @@ int journal_file_open_reliably(
JournalFile **ret);
#define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
+#define VALID64(x) (((x) & 7ULL) == 0ULL)
#define JOURNAL_HEADER_CONTAINS(h, field) \
(le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index f9a930e..7be0d2e 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -45,6 +45,8 @@
* */
static int journal_file_object_verify(JournalFile *f, Object *o) {
+ uint64_t i;
+
assert(f);
assert(o);
@@ -87,12 +89,22 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
if (h1 != h2)
return -EBADMSG;
+ if (!VALID64(o->data.next_hash_offset) ||
+ !VALID64(o->data.next_field_offset) ||
+ !VALID64(o->data.entry_offset) ||
+ !VALID64(o->data.entry_array_offset))
+ return -EBADMSG;
+
break;
}
case OBJECT_FIELD:
if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0)
return -EBADMSG;
+
+ if (!VALID64(o->field.next_hash_offset) ||
+ !VALID64(o->field.head_data_offset))
+ return -EBADMSG;
break;
case OBJECT_ENTRY:
@@ -106,6 +118,12 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
le64toh(o->entry.realtime) <= 0)
return -EBADMSG;
+ for (i = 0; i < journal_file_entry_n_items(o); i++) {
+ if (o->entry.items[i].object_offset == 0 ||
+ !VALID64(o->entry.items[i].object_offset))
+ return -EBADMSG;
+ }
+
break;
case OBJECT_DATA_HASH_TABLE:
@@ -125,6 +143,9 @@ static int journal_file_object_verify(JournalFile *f, Object *o) {
if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0)
return -EBADMSG;
+ if (!VALID64(o->entry_array.next_entry_array_offset))
+ return -EBADMSG;
+
break;
case OBJECT_TAG:
commit a0108012974558c5a7dcf8c76456be6a07b0e95d
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Aug 17 22:10:36 2012 +0200
journal: be fine with opening rotated/corrupted journal files
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 4d7a6ff..08d4285 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1957,7 +1957,8 @@ int journal_file_open(
(flags & O_ACCMODE) != O_RDWR)
return -EINVAL;
- if (!endswith(fname, ".journal"))
+ if (!endswith(fname, ".journal") &&
+ !endswith(fname, ".journal~"))
return -EINVAL;
f = new0(JournalFile, 1);
commit f982e6f7612401a9a789bb8f40d2adca34c85c10
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Aug 17 22:10:11 2012 +0200
journal: set secure deletion flags for FSS file
diff --git a/TODO b/TODO
index 102a813..875a3db 100644
--- a/TODO
+++ b/TODO
@@ -49,6 +49,8 @@ Bugfixes:
Features:
+* man: document in ExecStart= explicitly that we don't take shell command lines, only executable names with arguments
+
* shutdown: don't read-only mount anything when running in container
* nspawn: --read-only is not applied recursively to submounts
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 5c21ab0..25f41f6 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -30,6 +30,8 @@
#include <time.h>
#include <getopt.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
#include <systemd/sd-journal.h>
@@ -453,7 +455,7 @@ static int setup_keys(void) {
size_t mpk_size, seed_size, state_size, i;
uint8_t *mpk, *seed, *state;
ssize_t l;
- int fd = -1, r;
+ int fd = -1, r, attr = 0;
sd_id128_t machine, boot;
char *p = NULL, *k = NULL;
struct FSSHeader h;
@@ -530,6 +532,16 @@ static int setup_keys(void) {
goto finish;
}
+ /* Enable secure remove, exclusion from dump, synchronous
+ * writing and in-place updating */
+ if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
+ log_warning("FS_IOC_GETFLAGS failed: %m");
+
+ attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
+
+ if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
+ log_warning("FS_IOC_SETFLAGS failed: %m");
+
zero(h);
memcpy(h.signature, "KSHHRHLP", 8);
h.machine_id = machine;
More information about the systemd-commits
mailing list