• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.79
/src/journal/journalctl-authenticate.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "sd-json.h"
4

5
#include "ansi-color.h"
6
#include "chattr-util.h"
7
#include "errno-util.h"
8
#include "fd-util.h"
9
#include "fs-util.h"
10
#include "fsprg.h"
11
#include "hostname-setup.h"
12
#include "hostname-util.h"
13
#include "io-util.h"
14
#include "journal-authenticate.h"
15
#include "journalctl.h"
16
#include "journalctl-authenticate.h"
17
#include "log.h"
18
#include "memstream-util.h"
19
#include "path-util.h"
20
#include "qrcode-util.h"
21
#include "random-util.h"
22
#include "stat-util.h"
23
#include "terminal-util.h"
24
#include "tmpfile-util.h"
25

26
#if HAVE_GCRYPT
27
static int format_key(
6✔
28
                const void *seed,
29
                size_t seed_size,
30
                uint64_t start,
31
                uint64_t interval,
32
                char **ret) {
33

34
        _cleanup_(memstream_done) MemStream m = {};
6✔
35
        FILE *f;
6✔
36

37
        assert(seed);
6✔
38
        assert(seed_size > 0);
6✔
39
        assert(ret);
6✔
40

41
        f = memstream_init(&m);
6✔
42
        if (!f)
6✔
43
                return -ENOMEM;
44

45
        for (size_t i = 0; i < seed_size; i++) {
78✔
46
                if (i > 0 && i % 3 == 0)
72✔
47
                        fputc('-', f);
18✔
48
                fprintf(f, "%02x", ((uint8_t*) seed)[i]);
72✔
49
        }
50

51
        fprintf(f, "/%"PRIx64"-%"PRIx64, start, interval);
6✔
52

53
        return memstream_finalize(&m, ret, NULL);
6✔
54
}
55
#endif
56

57
int action_setup_keys(void) {
6✔
58
#if HAVE_GCRYPT
59
        _cleanup_(unlink_and_freep) char *tmpfile = NULL;
×
60
        _cleanup_close_ int fd = -EBADF;
6✔
61
        _cleanup_free_ char *path = NULL;
6✔
62
        size_t mpk_size, seed_size, state_size;
6✔
63
        uint8_t *mpk, *seed, *state;
6✔
64
        sd_id128_t machine, boot;
6✔
65
        uint64_t n;
6✔
66
        int r;
6✔
67

68
        assert(arg_action == ACTION_SETUP_KEYS);
6✔
69

70
        r = is_dir("/var/log/journal/", /* follow = */ false);
6✔
71
        if (r == 0)
6✔
72
                return log_error_errno(SYNTHETIC_ERRNO(ENOTDIR),
×
73
                                       "/var/log/journal is not a directory, must be using persistent logging for FSS.");
74
        if (r == -ENOENT)
6✔
75
                return log_error_errno(r, "Directory /var/log/journal/ does not exist, must be using persistent logging for FSS.");
×
76
        if (r < 0)
6✔
77
                return log_error_errno(r, "Failed to check if /var/log/journal/ is a directory: %m");
×
78

79
        r = sd_id128_get_machine(&machine);
6✔
80
        if (r < 0)
6✔
81
                return log_error_errno(r, "Failed to get machine ID: %m");
×
82

83
        r = sd_id128_get_boot(&boot);
6✔
84
        if (r < 0)
6✔
85
                return log_error_errno(r, "Failed to get boot ID: %m");
×
86

87
        path = path_join("/var/log/journal/", SD_ID128_TO_STRING(machine), "/fss");
6✔
88
        if (!path)
6✔
89
                return log_oom();
×
90

91
        if (arg_force) {
6✔
92
                if (unlink(path) < 0 && errno != ENOENT)
6✔
93
                        return log_error_errno(errno, "Failed to remove \"%s\": %m", path);
×
94
        } else if (access(path, F_OK) >= 0)
×
95
                return log_error_errno(SYNTHETIC_ERRNO(EEXIST),
×
96
                                       "Sealing key file %s exists already. Use --force to recreate.", path);
97

98
        mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
6✔
99
        mpk = alloca_safe(mpk_size);
6✔
100

101
        seed_size = FSPRG_RECOMMENDED_SEEDLEN;
6✔
102
        seed = alloca_safe(seed_size);
6✔
103

104
        state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
6✔
105
        state = alloca_safe(state_size);
6✔
106

107
        if (!arg_quiet)
6✔
108
                log_info("Generating seed...");
1✔
109
        r = crypto_random_bytes(seed, seed_size);
6✔
110
        if (r < 0)
6✔
111
                return log_error_errno(r, "Failed to acquire random seed: %m");
×
112

113
        if (!arg_quiet)
6✔
114
                log_info("Generating key pair...");
1✔
115
        r = FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
6✔
116
        if (r < 0)
6✔
117
                return log_error_errno(r, "Failed to generate key pair: %m");
×
118

119
        if (!arg_quiet)
6✔
120
                log_info("Generating sealing key...");
1✔
121
        r = FSPRG_GenState0(state, mpk, seed, seed_size);
6✔
122
        if (r < 0)
6✔
123
                return log_error_errno(r, "Failed to generate sealing key: %m");
×
124

125
        assert(arg_interval > 0);
6✔
126
        n = now(CLOCK_REALTIME);
6✔
127
        n /= arg_interval;
6✔
128

129
        fd = open_tmpfile_linkable(path, O_WRONLY|O_CLOEXEC, &tmpfile);
6✔
130
        if (fd < 0)
6✔
131
                return log_error_errno(fd, "Failed to open a temporary file for %s: %m", path);
×
132

133
        r = chattr_secret(fd, CHATTR_WARN_UNSUPPORTED_FLAGS);
6✔
134
        if (r < 0)
6✔
135
                log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || arg_quiet ? LOG_DEBUG : LOG_WARNING,
6✔
136
                               r, "Failed to set file attributes on a temporary file for '%s', ignoring: %m", path);
137

138
        struct FSSHeader h = {
6✔
139
                .signature = { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' },
140
                .machine_id = machine,
141
                .boot_id = boot,
142
                .header_size = htole64(sizeof(h)),
143
                .start_usec = htole64(n * arg_interval),
6✔
144
                .interval_usec = htole64(arg_interval),
145
                .fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR),
146
                .fsprg_state_size = htole64(state_size),
147
        };
148

149
        r = loop_write(fd, &h, sizeof(h));
6✔
150
        if (r < 0)
6✔
151
                return log_error_errno(r, "Failed to write header: %m");
×
152

153
        r = loop_write(fd, state, state_size);
6✔
154
        if (r < 0)
6✔
155
                return log_error_errno(r, "Failed to write state: %m");
×
156

157
        r = link_tmpfile(fd, tmpfile, path, /* flags = */ 0);
6✔
158
        if (r < 0)
6✔
159
                return log_error_errno(r, "Failed to link file: %m");
×
160

161
        tmpfile = mfree(tmpfile);
6✔
162

163
        _cleanup_free_ char *key = NULL;
6✔
164
        r = format_key(seed, seed_size, n, arg_interval, &key);
6✔
165
        if (r < 0)
6✔
166
                return r;
167

168
        if ((!on_tty() || arg_quiet) && !sd_json_format_enabled(arg_json_format_flags)) {
6✔
169
                /* If we are not on a TTY, show only the key. */
170
                puts(key);
2✔
171
                return 0;
172
        }
173

174
        _cleanup_free_ char *hn = NULL;
4✔
175
        hn = gethostname_malloc();
4✔
176
        if (hn)
4✔
177
                hostname_cleanup(hn);
4✔
178

179
        if (sd_json_format_enabled(arg_json_format_flags)) {
4✔
180
                _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
4✔
181

182
                if (arg_json_format_flags & (SD_JSON_FORMAT_SSE | SD_JSON_FORMAT_SEQ)) {
4✔
183
                        log_debug("Specified --output=%s with --setup-keys, migrating to --output=json.",
2✔
184
                                  FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_SSE) ? "json-sse" : "json-seq");
185
                        arg_json_format_flags &= ~(SD_JSON_FORMAT_SSE | SD_JSON_FORMAT_SEQ);
2✔
186
                        arg_json_format_flags |= SD_JSON_FORMAT_NEWLINE;
2✔
187
                }
188

189
                r = sd_json_buildo(
4✔
190
                                &v,
191
                                SD_JSON_BUILD_PAIR_ID128("machine", machine),
192
                                SD_JSON_BUILD_PAIR_STRING("hostname", hn),
193
                                SD_JSON_BUILD_PAIR_STRING("path", path),
194
                                SD_JSON_BUILD_PAIR_STRING("key", key));
195
                if (r < 0)
4✔
196
                        return log_error_errno(r, "Failed to build json object: %m");
×
197

198
                r = sd_json_variant_dump(v, arg_json_format_flags, /* f = */ NULL, /* prefix = */ NULL);
4✔
199
                if (r < 0)
4✔
200
                        return log_error_errno(r, "Failed to dump json object: %m");
×
201

202
                return 0;
203
        }
204

205
        fprintf(stderr,
×
206
                "\nNew keys have been generated for host %s%s" SD_ID128_FORMAT_STR ".\n"
207
                "\n"
208
                "The %ssecret sealing key%s has been written to the following local file.\n"
209
                "This key file is automatically updated when the sealing key is advanced.\n"
210
                "It should not be used on multiple hosts.\n"
211
                "\n"
212
                "\t%s\n"
213
                "\n"
214
                "The sealing key is automatically changed every %s.\n"
215
                "\n"
216
                "Please write down the following %ssecret verification key%s. It should be stored\n"
217
                "in a safe location and should not be saved locally on disk.\n"
218
                "\n\t%s",
219
                strempty(hn), hn ? "/" : "",
220
                SD_ID128_FORMAT_VAL(machine),
×
221
                ansi_highlight(), ansi_normal(),
222
                path,
223
                FORMAT_TIMESPAN(arg_interval, 0),
×
224
                ansi_highlight(), ansi_normal(),
225
                ansi_highlight_red());
226
        fflush(stderr);
×
227

228
        puts(key);
×
229

230
        fputs(ansi_normal(), stderr);
×
231

232
#if HAVE_QRENCODE
233
        _cleanup_free_ char *url = NULL;
×
234
        url = strjoin("fss://", key, "?machine=", SD_ID128_TO_STRING(machine), hn ? ";hostname=" : "", hn);
×
235
        if (!url)
×
236
                return log_oom();
×
237

238
        (void) print_qrcode(stderr, "Scan the verification key to transfer it to another device", url);
×
239
#endif
240

241
        return 0;
242
#else
243
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Forward-secure sealing not available.");
244
#endif
245
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc