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

systemd / systemd / 21846209963

09 Feb 2026 03:52PM UTC coverage: 72.697% (-0.02%) from 72.716%
21846209963

push

github

daandemeyer
meson: guard symlinks in sysconfdir behind install_sysconfidr

Symlinks to files inside sysconfdir are now only installed if
ìnstall_sysconfdir=true (which is the default).

If sshconfdir,sshdconfdir,shellprofiledir are not inside sysconfdir and
install_sysconfidr=false, these symlinks are still installed to the
configured directory.

311951 of 429113 relevant lines covered (72.7%)

1156102.48 hits per line

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

55.7
/src/shared/boot-entry.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "alloc-util.h"
4
#include "boot-entry.h"
5
#include "chase.h"
6
#include "fd-util.h"
7
#include "fileio.h"
8
#include "log.h"
9
#include "os-util.h"
10
#include "path-util.h"
11
#include "string-table.h"
12
#include "string-util.h"
13
#include "strv.h"
14
#include "utf8.h"
15

16
bool boot_entry_token_valid(const char *p) {
182✔
17
        return utf8_is_valid(p) && string_is_safe(p) && filename_is_valid(p);
182✔
18
}
19

20
static int entry_token_load_one(int rfd, const char *dir, BootEntryTokenType *type, char **token) {
184✔
21
        _cleanup_free_ char *buf = NULL, *p = NULL;
184✔
22
        _cleanup_fclose_ FILE *f = NULL;
184✔
23
        int r;
184✔
24

25
        assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
184✔
26
        assert(dir);
184✔
27
        assert(type);
184✔
28
        assert(*type == BOOT_ENTRY_TOKEN_AUTO);
184✔
29
        assert(token);
184✔
30

31
        p = path_join(dir, "entry-token");
184✔
32
        if (!p)
184✔
33
                return log_oom();
×
34

35
        r = chase_and_fopenat_unlocked(rfd, p, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f);
184✔
36
        if (r == -ENOENT)
184✔
37
                return 0;
38
        if (r < 0)
180✔
39
                return log_error_errno(r, "Failed to chase and open '%s': %m", p);
×
40

41
        r = read_line(f, NAME_MAX, &buf);
180✔
42
        if (r < 0)
180✔
43
                return log_error_errno(r, "Failed to read %s: %m", p);
×
44

45
        if (isempty(buf))
364✔
46
                return 0;
47

48
        if (!boot_entry_token_valid(buf)) {
180✔
49
                log_debug("Invalid entry token specified in %s, ignoring.", p);
×
50
                return 0;
×
51
        }
52

53
        *token = TAKE_PTR(buf);
180✔
54
        *type = BOOT_ENTRY_TOKEN_LITERAL;
180✔
55
        return 1;
180✔
56
}
57

58
static int entry_token_load(int rfd, const char *conf_root, BootEntryTokenType *type, char **token) {
182✔
59
        int r;
182✔
60

61
        assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
182✔
62
        assert(type);
182✔
63
        assert(*type == BOOT_ENTRY_TOKEN_AUTO);
182✔
64
        assert(token);
182✔
65

66
        if (conf_root)
182✔
67
                return entry_token_load_one(rfd, conf_root, type, token);
×
68

69
        FOREACH_STRING(path, "/etc/kernel", "/usr/lib/kernel") {
186✔
70
                r = entry_token_load_one(rfd, path, type, token);
184✔
71
                if (r != 0)
184✔
72
                        return r;
180✔
73
        }
74

75
        return 0;
2✔
76
}
77

78
static int entry_token_from_machine_id(sd_id128_t machine_id, BootEntryTokenType *type, char **token) {
2✔
79
        char *p;
2✔
80

81
        assert(type);
2✔
82
        assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_MACHINE_ID));
2✔
83
        assert(token);
2✔
84

85
        if (sd_id128_is_null(machine_id))
2✔
86
                return 0;
2✔
87

88
        p = strdup(SD_ID128_TO_STRING(machine_id));
×
89
        if (!p)
×
90
                return log_oom();
×
91

92
        *token = p;
×
93
        *type = BOOT_ENTRY_TOKEN_MACHINE_ID;
×
94
        return 1;
×
95
}
96

97
static int entry_token_from_os_release(int rfd, BootEntryTokenType *type, char **token) {
2✔
98
        _cleanup_free_ char *id = NULL, *image_id = NULL;
2✔
99
        int r;
2✔
100

101
        assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
2✔
102
        assert(type);
2✔
103
        assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_OS_IMAGE_ID, BOOT_ENTRY_TOKEN_OS_ID));
2✔
104
        assert(token);
2✔
105

106
        switch (*type) {
2✔
107
        case BOOT_ENTRY_TOKEN_AUTO:
2✔
108
                r = parse_os_release_at(rfd,
2✔
109
                                        "IMAGE_ID", &image_id,
110
                                        "ID",       &id);
111
                break;
112

113
        case BOOT_ENTRY_TOKEN_OS_IMAGE_ID:
×
114
                r = parse_os_release_at(rfd, "IMAGE_ID", &image_id);
×
115
                break;
116

117
        case BOOT_ENTRY_TOKEN_OS_ID:
×
118
                r = parse_os_release_at(rfd, "ID", &id);
×
119
                break;
120

121
        default:
×
122
                assert_not_reached();
×
123
        }
124
        if (r == -ENOENT)
2✔
125
                return 0;
126
        if (r < 0)
2✔
127
                return log_error_errno(r, "Failed to load /etc/os-release: %m");
×
128

129
        if (!isempty(image_id) && boot_entry_token_valid(image_id)) {
2✔
130
                *token = TAKE_PTR(image_id);
×
131
                *type = BOOT_ENTRY_TOKEN_OS_IMAGE_ID;
×
132
                return 1;
×
133
        }
134

135
        if (!isempty(id) && boot_entry_token_valid(id)) {
6✔
136
                *token = TAKE_PTR(id);
2✔
137
                *type = BOOT_ENTRY_TOKEN_OS_ID;
2✔
138
                return 1;
2✔
139
        }
140

141
        return 0;
142
}
143

144
int boot_entry_token_ensure_at(
182✔
145
                int rfd,
146
                const char *conf_root,
147
                sd_id128_t machine_id,
148
                bool machine_id_is_random,
149
                BootEntryTokenType *type,
150
                char **token) {
151

152
        int r;
182✔
153

154
        assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
182✔
155
        assert(type);
182✔
156
        assert(token);
182✔
157

158
        /* Returns -EUNATCH if the selected token is not set */
159

160
        if (*token)
182✔
161
                return 0; /* Already set. */
162

163
        switch (*type) {
182✔
164

165
        case BOOT_ENTRY_TOKEN_AUTO:
182✔
166
                r = entry_token_load(rfd, conf_root, type, token);
182✔
167
                if (r != 0)
182✔
168
                        return r;
169

170
                if (!machine_id_is_random) {
2✔
171
                        r = entry_token_from_machine_id(machine_id, type, token);
2✔
172
                        if (r != 0)
2✔
173
                                return r;
174
                }
175

176
                r = entry_token_from_os_release(rfd, type, token);
2✔
177
                if (r != 0)
2✔
178
                        return r;
179

180
                if (machine_id_is_random) {
×
181
                        r = entry_token_from_machine_id(machine_id, type, token);
×
182
                        if (r != 0)
×
183
                                return r;
184
                }
185

186
                return log_error_errno(SYNTHETIC_ERRNO(EUNATCH),
×
187
                                       "No machine ID set, and /etc/os-release carries no ID=/IMAGE_ID= fields.");
188

189
        case BOOT_ENTRY_TOKEN_MACHINE_ID:
×
190
                r = entry_token_from_machine_id(machine_id, type, token);
×
191
                if (r != 0)
×
192
                        return r;
193

194
                return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "No machine ID set.");
×
195

196
        case BOOT_ENTRY_TOKEN_OS_IMAGE_ID:
×
197
                r = entry_token_from_os_release(rfd, type, token);
×
198
                if (r != 0)
×
199
                        return r;
200

201
                return log_error_errno(SYNTHETIC_ERRNO(EUNATCH),
×
202
                                       "IMAGE_ID= field not set in /etc/os-release.");
203

204
        case BOOT_ENTRY_TOKEN_OS_ID:
×
205
                r = entry_token_from_os_release(rfd, type, token);
×
206
                if (r != 0)
×
207
                        return r;
208

209
                return log_error_errno(SYNTHETIC_ERRNO(EUNATCH),
×
210
                                       "ID= field not set in /etc/os-release.");
211

212
        case BOOT_ENTRY_TOKEN_LITERAL:
213
                /* In this case, the token should be already set by the user input. */
214
                return log_error_errno(SYNTHETIC_ERRNO(EUNATCH), "Literal token indicated but not specified.");
×
215

216
        default:
×
217
                assert_not_reached();
×
218
        }
219
}
220

221
int boot_entry_token_ensure(
32✔
222
                const char *root,
223
                const char *conf_root,
224
                sd_id128_t machine_id,
225
                bool machine_id_is_random,
226
                BootEntryTokenType *type,
227
                char **token) {
228

229
        assert(token);
32✔
230

231
        if (*token)
32✔
232
                return 0; /* Already set. */
32✔
233

234
        _cleanup_close_ int rfd = XAT_FDROOT;
32✔
235
        if (!empty_or_root(root)) {
32✔
236
                rfd = open(root, O_CLOEXEC | O_DIRECTORY | O_PATH);
6✔
237
                if (rfd < 0)
6✔
238
                        return -errno;
×
239
        }
240

241
        return boot_entry_token_ensure_at(rfd, conf_root, machine_id, machine_id_is_random, type, token);
32✔
242
}
243

244
int parse_boot_entry_token_type(const char *s, BootEntryTokenType *type, char **token) {
×
245
        assert(s);
×
246
        assert(type);
×
247
        assert(token);
×
248

249
        /*
250
         * This function is intended to be used in command line parsers, to handle token that are passed in.
251
         *
252
         * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS!
253
         * Hence, do not pass in uninitialized pointers.
254
         */
255

256
        if (streq(s, "machine-id")) {
×
257
                *type = BOOT_ENTRY_TOKEN_MACHINE_ID;
×
258
                *token = mfree(*token);
×
259
                return 0;
×
260
        }
261

262
        if (streq(s, "os-image-id")) {
×
263
                *type = BOOT_ENTRY_TOKEN_OS_IMAGE_ID;
×
264
                *token = mfree(*token);
×
265
                return 0;
×
266
        }
267

268
        if (streq(s, "os-id")) {
×
269
                *type = BOOT_ENTRY_TOKEN_OS_ID;
×
270
                *token = mfree(*token);
×
271
                return 0;
×
272
        }
273

274
        const char *e = startswith(s, "literal:");
×
275
        if (e) {
×
276
                if (!boot_entry_token_valid(e))
×
277
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
278
                                               "Invalid entry token literal is specified for --entry-token=.");
279

280
                *type = BOOT_ENTRY_TOKEN_LITERAL;
×
281
                return free_and_strdup_warn(token, e);
×
282
        }
283

284
        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
285
                               "Unexpected parameter for --entry-token=: %s", s);
286
}
287

288
static const char *const boot_entry_token_type_table[] = {
289
        [BOOT_ENTRY_TOKEN_MACHINE_ID]  = "machine-id",
290
        [BOOT_ENTRY_TOKEN_OS_IMAGE_ID] = "os-image-id",
291
        [BOOT_ENTRY_TOKEN_OS_ID]       = "os-id",
292
        [BOOT_ENTRY_TOKEN_LITERAL]     = "literal",
293
        [BOOT_ENTRY_TOKEN_AUTO]        = "auto",
294
};
295

296
DEFINE_STRING_TABLE_LOOKUP(boot_entry_token_type, BootEntryTokenType);
×
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