summaryrefslogtreecommitdiffstats
path: root/src/libsystemd/sd-journal
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-journal')
-rw-r--r--src/libsystemd/sd-journal/journal-authenticate.c28
-rw-r--r--src/libsystemd/sd-journal/journal-file.c129
-rw-r--r--src/libsystemd/sd-journal/journal-file.h30
-rw-r--r--src/libsystemd/sd-journal/journal-verify.c4
4 files changed, 89 insertions, 102 deletions
diff --git a/src/libsystemd/sd-journal/journal-authenticate.c b/src/libsystemd/sd-journal/journal-authenticate.c
index 83cbf4128e..fd7ee427be 100644
--- a/src/libsystemd/sd-journal/journal-authenticate.c
+++ b/src/libsystemd/sd-journal/journal-authenticate.c
@@ -31,7 +31,7 @@ int journal_file_append_tag(JournalFile *f) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
if (!f->hmac_running)
@@ -69,7 +69,7 @@ int journal_file_hmac_start(JournalFile *f) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
if (f->hmac_running)
@@ -94,7 +94,7 @@ static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *e
assert(f);
assert(epoch);
- assert(f->seal);
+ assert(JOURNAL_HEADER_SEALED(f->header));
if (f->fss_start_usec == 0 ||
f->fss_interval_usec == 0)
@@ -115,7 +115,7 @@ static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
int r;
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
r = journal_file_get_epoch(f, realtime, &goal);
@@ -135,7 +135,7 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
r = journal_file_get_epoch(f, realtime, &goal);
@@ -163,7 +163,7 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
assert(f->fsprg_seed);
@@ -199,7 +199,7 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
if (realtime <= 0)
@@ -225,7 +225,7 @@ int journal_file_hmac_put_object(JournalFile *f, ObjectType type, Object *o, uin
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
r = journal_file_hmac_start(f);
@@ -285,7 +285,7 @@ int journal_file_hmac_put_header(JournalFile *f) {
assert(f);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
r = journal_file_hmac_start(f);
@@ -316,8 +316,8 @@ int journal_file_fss_load(JournalFile *f) {
assert(f);
- if (!f->seal)
- return 0;
+ /* This function is used to determine whether sealing should be enabled in the journal header so we
+ * can't check the header to check if sealing is enabled here. */
r = sd_id128_get_machine(&machine);
if (r < 0)
@@ -418,7 +418,7 @@ finish:
int journal_file_hmac_setup(JournalFile *f) {
gcry_error_t e;
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
initialize_libgcrypt(true);
@@ -434,7 +434,7 @@ int journal_file_append_first_tag(JournalFile *f) {
int r;
uint64_t p;
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return 0;
log_debug("Calculating first tag...");
@@ -530,7 +530,7 @@ bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
assert(f);
assert(u);
- if (!f->seal)
+ if (!JOURNAL_HEADER_SEALED(f->header))
return false;
epoch = FSPRG_GetEpoch(f->fsprg_state);
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c
index 4292679b5f..a7c65b1ccd 100644
--- a/src/libsystemd/sd-journal/journal-file.c
+++ b/src/libsystemd/sd-journal/journal-file.c
@@ -191,7 +191,7 @@ static int journal_file_set_online(JournalFile *f) {
assert(f);
- if (!f->writable)
+ if (!journal_file_writable(f))
return -EPERM;
if (f->fd < 0 || !f->header)
@@ -285,24 +285,38 @@ JournalFile* journal_file_close(JournalFile *f) {
return mfree(f);
}
-static int journal_file_init_header(JournalFile *f, JournalFile *template) {
+static int journal_file_init_header(JournalFile *f, JournalFileFlags file_flags, JournalFile *template) {
Header h = {};
ssize_t k;
+ bool keyed_hash, seal = false;
int r;
assert(f);
+ /* We turn on keyed hashes by default, but provide an environment variable to turn them off, if
+ * people really want that */
+ r = getenv_bool("SYSTEMD_JOURNAL_KEYED_HASH");
+ if (r < 0) {
+ if (r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_KEYED_HASH environment variable, ignoring: %m");
+ keyed_hash = true;
+ } else
+ keyed_hash = r;
+
+#if HAVE_GCRYPT
+ /* Try to load the FSPRG state, and if we can't, then just don't do sealing */
+ seal = FLAGS_SET(file_flags, JOURNAL_SEAL) && journal_file_fss_load(f) >= 0;
+#endif
+
memcpy(h.signature, HEADER_SIGNATURE, 8);
h.header_size = htole64(ALIGN64(sizeof(h)));
h.incompatible_flags |= htole32(
- f->compress_xz * HEADER_INCOMPATIBLE_COMPRESSED_XZ |
- f->compress_lz4 * HEADER_INCOMPATIBLE_COMPRESSED_LZ4 |
- f->compress_zstd * HEADER_INCOMPATIBLE_COMPRESSED_ZSTD |
- f->keyed_hash * HEADER_INCOMPATIBLE_KEYED_HASH);
+ FLAGS_SET(file_flags, JOURNAL_COMPRESS) *
+ COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(DEFAULT_COMPRESSION) |
+ keyed_hash * HEADER_INCOMPATIBLE_KEYED_HASH);
- h.compatible_flags = htole32(
- f->seal * HEADER_COMPATIBLE_SEALED);
+ h.compatible_flags = htole32(seal * HEADER_COMPATIBLE_SEALED);
r = sd_id128_randomize(&h.file_id);
if (r < 0)
@@ -409,7 +423,7 @@ static int journal_file_verify_header(JournalFile *f) {
return -EPROTONOSUPPORT;
/* When open for writing we refuse to open files with compatible flags, too. */
- if (f->writable && warn_wrong_flags(f, true))
+ if (journal_file_writable(f) && warn_wrong_flags(f, true))
return -EPROTONOSUPPORT;
if (f->header->state >= _STATE_MAX)
@@ -438,7 +452,7 @@ static int journal_file_verify_header(JournalFile *f) {
!VALID64(le64toh(f->header->entry_array_offset)))
return -ENODATA;
- if (f->writable) {
+ if (journal_file_writable(f)) {
sd_id128_t machine_id;
uint8_t state;
int r;
@@ -475,14 +489,6 @@ static int journal_file_verify_header(JournalFile *f) {
f->path);
}
- f->compress_xz = JOURNAL_HEADER_COMPRESSED_XZ(f->header);
- f->compress_lz4 = JOURNAL_HEADER_COMPRESSED_LZ4(f->header);
- f->compress_zstd = JOURNAL_HEADER_COMPRESSED_ZSTD(f->header);
-
- f->seal = JOURNAL_HEADER_SEALED(f->header);
-
- f->keyed_hash = JOURNAL_HEADER_KEYED_HASH(f->header);
-
return 0;
}
@@ -1240,7 +1246,7 @@ static int next_hash_offset(
(*depth)++;
/* If the depth of this hash chain is larger than all others we have seen so far, record it */
- if (header_max_depth && f->writable)
+ if (header_max_depth && journal_file_writable(f))
*header_max_depth = htole64(MAX(*depth, le64toh(*header_max_depth)));
}
@@ -1589,7 +1595,7 @@ static int journal_file_append_data(
compression = compress_blob(data, size, o->data.payload, size - 1, &rsize);
if (compression > COMPRESSION_NONE) {
o->object.size = htole64(offsetof(Object, data.payload) + rsize);
- o->object.flags |= COMPRESSION_TO_MASK(compression);
+ o->object.flags |= COMPRESSION_TO_OBJECT_FLAG(compression);
log_debug("Compressed data object %"PRIu64" -> %zu using %s",
size, rsize, compression_to_string(compression));
@@ -3372,54 +3378,12 @@ int journal_file_open(
*f = (JournalFile) {
.fd = fd,
.mode = mode,
-
.open_flags = open_flags,
- .writable = (open_flags & O_ACCMODE) != O_RDONLY,
-
.compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?
DEFAULT_COMPRESS_THRESHOLD :
MAX(MIN_COMPRESS_THRESHOLD, compress_threshold_bytes),
-#if HAVE_GCRYPT
- .seal = FLAGS_SET(file_flags, JOURNAL_SEAL),
-#endif
};
- if (DEFAULT_COMPRESSION == COMPRESSION_ZSTD)
- f->compress_zstd = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
- else if (DEFAULT_COMPRESSION == COMPRESSION_LZ4)
- f->compress_lz4 = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
- else if (DEFAULT_COMPRESSION == COMPRESSION_XZ)
- f->compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
-
- /* We turn on keyed hashes by default, but provide an environment variable to turn them off, if
- * people really want that */
- r = getenv_bool("SYSTEMD_JOURNAL_KEYED_HASH");
- if (r < 0) {
- if (r != -ENXIO)
- log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_KEYED_HASH environment variable, ignoring: %m");
- f->keyed_hash = true;
- } else
- f->keyed_hash = r;
-
- if (DEBUG_LOGGING) {
- static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
- static uint64_t last_bytes = UINT64_MAX;
-
- if (last_seal != f->seal ||
- last_keyed_hash != f->keyed_hash ||
- last_compress != JOURNAL_FILE_COMPRESS(f) ||
- last_bytes != f->compress_threshold_bytes) {
-
- log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
- yes_no(f->seal), yes_no(f->keyed_hash), yes_no(JOURNAL_FILE_COMPRESS(f)),
- FORMAT_BYTES(f->compress_threshold_bytes));
- last_seal = f->seal;
- last_keyed_hash = f->keyed_hash;
- last_compress = JOURNAL_FILE_COMPRESS(f);
- last_bytes = f->compress_threshold_bytes;
- }
- }
-
if (fname) {
f->path = strdup(fname);
if (!f->path) {
@@ -3471,7 +3435,7 @@ int journal_file_open(
goto fail;
/* If we just got the fd passed in, we don't really know if we created the file anew */
- newly_created = f->last_stat.st_size == 0 && f->writable;
+ newly_created = f->last_stat.st_size == 0 && journal_file_writable(f);
}
f->cache_fd = mmap_cache_add_fd(mmap_cache, f->fd, prot_from_flags(open_flags));
@@ -3490,17 +3454,7 @@ int journal_file_open(
* solely on mtime/atime/ctime of the file. */
(void) fd_setcrtime(f->fd, 0);
-#if HAVE_GCRYPT
- /* Try to load the FSPRG state, and if we can't, then
- * just don't do sealing */
- if (f->seal) {
- r = journal_file_fss_load(f);
- if (r < 0)
- f->seal = false;
- }
-#endif
-
- r = journal_file_init_header(f, template);
+ r = journal_file_init_header(f, file_flags, template);
if (r < 0)
goto fail;
@@ -3534,14 +3488,14 @@ int journal_file_open(
}
#if HAVE_GCRYPT
- if (!newly_created && f->writable) {
+ if (!newly_created && journal_file_writable(f) && JOURNAL_HEADER_SEALED(f->header)) {
r = journal_file_fss_load(f);
if (r < 0)
goto fail;
}
#endif
- if (f->writable) {
+ if (journal_file_writable(f)) {
if (metrics) {
journal_default_metrics(metrics, f->fd);
f->metrics = *metrics;
@@ -3593,6 +3547,25 @@ int journal_file_open(
/* The file is opened now successfully, thus we take possession of any passed in fd. */
f->close_fd = true;
+ if (DEBUG_LOGGING) {
+ static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
+ static uint64_t last_bytes = UINT64_MAX;
+
+ if (last_seal != JOURNAL_HEADER_SEALED(f->header) ||
+ last_keyed_hash != JOURNAL_HEADER_KEYED_HASH(f->header) ||
+ last_compress != JOURNAL_FILE_COMPRESS(f) ||
+ last_bytes != f->compress_threshold_bytes) {
+
+ log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
+ yes_no(JOURNAL_HEADER_SEALED(f->header)), yes_no(JOURNAL_HEADER_KEYED_HASH(f->header)),
+ yes_no(JOURNAL_FILE_COMPRESS(f)), FORMAT_BYTES(f->compress_threshold_bytes));
+ last_seal = JOURNAL_HEADER_SEALED(f->header);
+ last_keyed_hash = JOURNAL_HEADER_KEYED_HASH(f->header);
+ last_compress = JOURNAL_FILE_COMPRESS(f);
+ last_bytes = f->compress_threshold_bytes;
+ }
+ }
+
*ret = f;
return 0;
@@ -3613,7 +3586,7 @@ int journal_file_archive(JournalFile *f, char **ret_previous_path) {
assert(f);
- if (!f->writable)
+ if (!journal_file_writable(f))
return -EINVAL;
/* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
@@ -3693,7 +3666,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
assert(o);
assert(p);
- if (!to->writable)
+ if (!journal_file_writable(to))
return -EPERM;
ts = (dual_timestamp) {
diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h
index 04266958c1..64b15eabed 100644
--- a/src/libsystemd/sd-journal/journal-file.h
+++ b/src/libsystemd/sd-journal/journal-file.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <fcntl.h>
#include <inttypes.h>
#include <sys/uio.h>
@@ -64,14 +65,8 @@ typedef struct JournalFile {
mode_t mode;
int open_flags;
- bool writable:1;
- bool compress_xz:1;
- bool compress_lz4:1;
- bool compress_zstd:1;
- bool seal:1;
bool close_fd:1;
bool archive:1;
- bool keyed_hash:1;
direction_t last_direction;
LocationType location_type;
@@ -258,7 +253,8 @@ int journal_file_map_field_hash_table(JournalFile *f);
static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) {
assert(f);
- return f->compress_xz || f->compress_lz4 || f->compress_zstd;
+ return JOURNAL_HEADER_COMPRESSED_XZ(f->header) || JOURNAL_HEADER_COMPRESSED_LZ4(f->header) ||
+ JOURNAL_HEADER_COMPRESSED_ZSTD(f->header);
}
uint64_t journal_file_hash_data(JournalFile *f, const void *data, size_t sz);
@@ -284,7 +280,7 @@ static inline Compression COMPRESSION_FROM_OBJECT(const Object *o) {
}
}
-static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
+static inline uint8_t COMPRESSION_TO_OBJECT_FLAG(Compression c) {
switch (c) {
case COMPRESSION_XZ:
return OBJECT_COMPRESSED_XZ;
@@ -296,3 +292,21 @@ static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
return 0;
}
}
+
+static inline uint32_t COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(Compression c) {
+ switch (c) {
+ case COMPRESSION_XZ:
+ return HEADER_INCOMPATIBLE_COMPRESSED_XZ;
+ case COMPRESSION_LZ4:
+ return HEADER_INCOMPATIBLE_COMPRESSED_LZ4;
+ case COMPRESSION_ZSTD:
+ return HEADER_INCOMPATIBLE_COMPRESSED_ZSTD;
+ default:
+ return 0;
+ }
+}
+
+static inline bool journal_file_writable(JournalFile *f) {
+ assert(f);
+ return (f->open_flags & O_ACCMODE) != O_RDONLY;
+}
diff --git a/src/libsystemd/sd-journal/journal-verify.c b/src/libsystemd/sd-journal/journal-verify.c
index 21a5b1ca9e..1495450394 100644
--- a/src/libsystemd/sd-journal/journal-verify.c
+++ b/src/libsystemd/sd-journal/journal-verify.c
@@ -842,7 +842,7 @@ int journal_file_verify(
#else
return -EOPNOTSUPP;
#endif
- } else if (f->seal)
+ } else if (JOURNAL_HEADER_SEALED(f->header))
return -ENOKEY;
r = var_tmp_dir(&tmp_dir);
@@ -1130,7 +1130,7 @@ int journal_file_verify(
}
#if HAVE_GCRYPT
- if (f->seal) {
+ if (JOURNAL_HEADER_SEALED(f->header)) {
uint64_t q, rt;
debug(p, "Checking tag %"PRIu64"...", le64toh(o->tag.seqnum));