]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: Use header macros everywhere instead of JournalFile fields
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 20 Apr 2022 14:52:21 +0000 (16:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 3 May 2022 15:23:02 +0000 (17:23 +0200)
Let's standardize on the journal header as a single source of truth
and remove redundant information from the JournalFile struct.

src/journal/managed-journal-file.c
src/libsystemd/sd-journal/journal-authenticate.c
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-file.h
src/libsystemd/sd-journal/journal-verify.c

index 7e89bb30d900ba1bc06f179819e4cc816351049c..52aee7be981aab5b7a853884270286d5501cf442 100644 (file)
@@ -73,7 +73,7 @@ static int managed_journal_file_entry_array_punch_hole(JournalFile *f, uint64_t
         if (sz < MINIMUM_HOLE_SIZE)
                 return 0;
 
-        if (p == le64toh(f->header->tail_object_offset) && !f->seal) {
+        if (p == le64toh(f->header->tail_object_offset) && !JOURNAL_HEADER_SEALED(f->header)) {
                 ssize_t n;
 
                 o.object.size = htole64(offset - p);
@@ -292,7 +292,7 @@ int managed_journal_file_set_offline(ManagedJournalFile *f, bool wait) {
 
         assert(f);
 
-        if (!f->file->writable)
+        if (!journal_file_writable(f->file))
                 return -EPERM;
 
         if (f->file->fd < 0 || !f->file->header)
@@ -367,7 +367,7 @@ ManagedJournalFile* managed_journal_file_close(ManagedJournalFile *f) {
 
 #if HAVE_GCRYPT
         /* Write the final tag */
-        if (f->file->seal && f->file->writable) {
+        if (JOURNAL_HEADER_SEALED(f->file->header) && journal_file_writable(f->file)) {
                 int r;
 
                 r = journal_file_append_tag(f->file);
index 83cbf4128e3177dd0e6d434aa0138a34160c1e24..fd7ee427be459457431802a72fbbfd020e742d5d 100644 (file)
@@ -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);
index 4292679b5f20ac433f0fb46cc6b4ac0fe78aefe1..a7c65b1ccda3415c0d3c9536ff6c3e6e45e80af6 100644 (file)
@@ -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) {
index 04266958c1276507b67792c16dc622ff999bc19d..64b15eabedf25b6911d8465d434468653d172919 100644 (file)
@@ -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;
+}
index 21a5b1ca9e16006a0e010520a18955d045d24f13..149545039491d6f1defba379fa2f9d9eb1ed4541 100644 (file)
@@ -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));