Bug Summary

File:build-scan/../src/shared/bootspec.c
Warning:line 119, column 9
Value stored to 'tmp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name bootspec.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/shared/libsystemd-shared-239.a.p -I src/shared -I ../src/shared -I src/basic -I ../src/basic -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/shared/bootspec.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <stdio.h>
4#include <linux1/magic.h>
5
6#include "sd-id128.h"
7
8#include "alloc-util.h"
9#include "blkid-util.h"
10#include "bootspec.h"
11#include "conf-files.h"
12#include "def.h"
13#include "device-nodes.h"
14#include "efivars.h"
15#include "fd-util.h"
16#include "fileio.h"
17#include "parse-util.h"
18#include "stat-util.h"
19#include "string-util.h"
20#include "strv.h"
21#include "virt.h"
22
23void boot_entry_free(BootEntry *entry) {
24 assert(entry)do { if ((__builtin_expect(!!(!(entry)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("entry"), "../src/shared/bootspec.c", 24
, __PRETTY_FUNCTION__); } while (0)
;
25
26 free(entry->filename);
27 free(entry->title);
28 free(entry->show_title);
29 free(entry->version);
30 free(entry->machine_id);
31 free(entry->architecture);
32 strv_free(entry->options);
33 free(entry->kernel);
34 free(entry->efi);
35 strv_free(entry->initrd);
36 free(entry->device_tree);
37}
38
39int boot_entry_load(const char *path, BootEntry *entry) {
40 _cleanup_(boot_entry_free)__attribute__((cleanup(boot_entry_free))) BootEntry tmp = {};
41 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
42 unsigned line = 1;
43 char *b, *c;
44 int r;
45
46 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/shared/bootspec.c", 46,
__PRETTY_FUNCTION__); } while (0)
;
47 assert(entry)do { if ((__builtin_expect(!!(!(entry)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("entry"), "../src/shared/bootspec.c", 47
, __PRETTY_FUNCTION__); } while (0)
;
48
49 c = endswith_no_case(path, ".conf");
50 if (!c) {
51 log_error("Invalid loader entry filename: %s", path)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 51, __func__, "Invalid loader entry filename: %s"
, path) : -abs(_e); })
;
52 return -EINVAL22;
53 }
54
55 b = basename(path);
56 tmp.filename = strndup(b, c - b);
57 if (!tmp.filename)
58 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bootspec.c"
, 58, __func__)
;
59
60 f = fopen(path, "re");
61 if (!f)
62 return log_error_errno(errno, "Failed to open \"%s\": %m", path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 62, __func__
, "Failed to open \"%s\": %m", path) : -abs(_e); })
;
63
64 for (;;) {
65 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0), *field = NULL((void*)0);
66 const char *p;
67
68 r = read_line(f, LONG_LINE_MAX(1U*1024U*1024U), &buf);
69 if (r == 0)
70 break;
71 if (r == -ENOBUFS105)
72 return log_error_errno(r, "%s:%u: Line too long", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 72, __func__, "%s:%u: Line too long"
, path, line) : -abs(_e); })
;
73 if (r < 0)
74 return log_error_errno(r, "%s:%u: Error while reading: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 74, __func__, "%s:%u: Error while reading: %m"
, path, line) : -abs(_e); })
;
75
76 line++;
77
78 if (IN_SET(*strstrip(buf), '#', '\0')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){'#', '\0'})/sizeof(int)]; switch(*strstrip
(buf)) { case '#': case '\0': _found = 1; break; default: break
; } _found; })
)
79 continue;
80
81 p = buf;
82 r = extract_first_word(&p, &field, " \t", 0);
83 if (r < 0) {
84 log_error_errno(r, "Failed to parse config file %s line %u: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 84, __func__, "Failed to parse config file %s line %u: %m"
, path, line) : -abs(_e); })
;
85 continue;
86 }
87 if (r == 0) {
88 log_warning("%s:%u: Bad syntax", path, line)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 88, __func__, "%s:%u: Bad syntax"
, path, line) : -abs(_e); })
;
89 continue;
90 }
91
92 if (streq(field, "title")(strcmp((field),("title")) == 0))
93 r = free_and_strdup(&tmp.title, p);
94 else if (streq(field, "version")(strcmp((field),("version")) == 0))
95 r = free_and_strdup(&tmp.version, p);
96 else if (streq(field, "machine-id")(strcmp((field),("machine-id")) == 0))
97 r = free_and_strdup(&tmp.machine_id, p);
98 else if (streq(field, "architecture")(strcmp((field),("architecture")) == 0))
99 r = free_and_strdup(&tmp.architecture, p);
100 else if (streq(field, "options")(strcmp((field),("options")) == 0))
101 r = strv_extend(&tmp.options, p);
102 else if (streq(field, "linux")(strcmp((field),("linux")) == 0))
103 r = free_and_strdup(&tmp.kernel, p);
104 else if (streq(field, "efi")(strcmp((field),("efi")) == 0))
105 r = free_and_strdup(&tmp.efi, p);
106 else if (streq(field, "initrd")(strcmp((field),("initrd")) == 0))
107 r = strv_extend(&tmp.initrd, p);
108 else if (streq(field, "devicetree")(strcmp((field),("devicetree")) == 0))
109 r = free_and_strdup(&tmp.device_tree, p);
110 else {
111 log_notice("%s:%u: Unknown line \"%s\"", path, line, field)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 111, __func__, "%s:%u: Unknown line \"%s\""
, path, line, field) : -abs(_e); })
;
112 continue;
113 }
114 if (r < 0)
115 return log_error_errno(r, "%s:%u: Error while reading: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 115, __func__, "%s:%u: Error while reading: %m"
, path, line) : -abs(_e); })
;
116 }
117
118 *entry = tmp;
119 tmp = (BootEntry) {};
Value stored to 'tmp' is never read
120 return 0;
121}
122
123void boot_config_free(BootConfig *config) {
124 size_t i;
125
126 assert(config)do { if ((__builtin_expect(!!(!(config)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("config"), "../src/shared/bootspec.c", 126
, __PRETTY_FUNCTION__); } while (0)
;
127
128 free(config->default_pattern);
129 free(config->timeout);
130 free(config->editor);
131 free(config->auto_entries);
132 free(config->auto_firmware);
133
134 free(config->entry_oneshot);
135 free(config->entry_default);
136
137 for (i = 0; i < config->n_entries; i++)
138 boot_entry_free(config->entries + i);
139 free(config->entries);
140}
141
142int boot_loader_read_conf(const char *path, BootConfig *config) {
143 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
144 unsigned line = 1;
145 int r;
146
147 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/shared/bootspec.c", 147
, __PRETTY_FUNCTION__); } while (0)
;
148 assert(config)do { if ((__builtin_expect(!!(!(config)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("config"), "../src/shared/bootspec.c", 148
, __PRETTY_FUNCTION__); } while (0)
;
149
150 f = fopen(path, "re");
151 if (!f)
152 return log_error_errno(errno, "Failed to open \"%s\": %m", path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 152, __func__
, "Failed to open \"%s\": %m", path) : -abs(_e); })
;
153
154 for (;;) {
155 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0), *field = NULL((void*)0);
156 const char *p;
157
158 r = read_line(f, LONG_LINE_MAX(1U*1024U*1024U), &buf);
159 if (r == 0)
160 break;
161 if (r == -ENOBUFS105)
162 return log_error_errno(r, "%s:%u: Line too long", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 162, __func__, "%s:%u: Line too long"
, path, line) : -abs(_e); })
;
163 if (r < 0)
164 return log_error_errno(r, "%s:%u: Error while reading: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 164, __func__, "%s:%u: Error while reading: %m"
, path, line) : -abs(_e); })
;
165
166 line++;
167
168 if (IN_SET(*strstrip(buf), '#', '\0')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){'#', '\0'})/sizeof(int)]; switch(*strstrip
(buf)) { case '#': case '\0': _found = 1; break; default: break
; } _found; })
)
169 continue;
170
171 p = buf;
172 r = extract_first_word(&p, &field, " \t", 0);
173 if (r < 0) {
174 log_error_errno(r, "Failed to parse config file %s line %u: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 174, __func__, "Failed to parse config file %s line %u: %m"
, path, line) : -abs(_e); })
;
175 continue;
176 }
177 if (r == 0) {
178 log_warning("%s:%u: Bad syntax", path, line)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 178, __func__, "%s:%u: Bad syntax"
, path, line) : -abs(_e); })
;
179 continue;
180 }
181
182 if (streq(field, "default")(strcmp((field),("default")) == 0))
183 r = free_and_strdup(&config->default_pattern, p);
184 else if (streq(field, "timeout")(strcmp((field),("timeout")) == 0))
185 r = free_and_strdup(&config->timeout, p);
186 else if (streq(field, "editor")(strcmp((field),("editor")) == 0))
187 r = free_and_strdup(&config->editor, p);
188 else if (streq(field, "auto-entries")(strcmp((field),("auto-entries")) == 0))
189 r = free_and_strdup(&config->auto_entries, p);
190 else if (streq(field, "auto-firmware")(strcmp((field),("auto-firmware")) == 0))
191 r = free_and_strdup(&config->auto_firmware, p);
192 else if (streq(field, "console-mode")(strcmp((field),("console-mode")) == 0))
193 r = free_and_strdup(&config->console_mode, p);
194 else {
195 log_notice("%s:%u: Unknown line \"%s\"", path, line, field)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 195, __func__, "%s:%u: Unknown line \"%s\""
, path, line, field) : -abs(_e); })
;
196 continue;
197 }
198 if (r < 0)
199 return log_error_errno(r, "%s:%u: Error while reading: %m", path, line)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 199, __func__, "%s:%u: Error while reading: %m"
, path, line) : -abs(_e); })
;
200 }
201
202 return 0;
203}
204
205static int boot_entry_compare(const void *a, const void *b) {
206 const BootEntry *aa = a, *bb = b;
207
208 return str_verscmp(aa->filename, bb->filename);
209}
210
211int boot_entries_find(const char *dir, BootEntry **ret_entries, size_t *ret_n_entries) {
212 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **files = NULL((void*)0);
213 char **f;
214 int r;
215 BootEntry *array = NULL((void*)0);
216 size_t n_allocated = 0, n = 0;
217
218 assert(dir)do { if ((__builtin_expect(!!(!(dir)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dir"), "../src/shared/bootspec.c", 218,
__PRETTY_FUNCTION__); } while (0)
;
219 assert(ret_entries)do { if ((__builtin_expect(!!(!(ret_entries)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret_entries"), "../src/shared/bootspec.c"
, 219, __PRETTY_FUNCTION__); } while (0)
;
220 assert(ret_n_entries)do { if ((__builtin_expect(!!(!(ret_n_entries)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret_n_entries"), "../src/shared/bootspec.c"
, 220, __PRETTY_FUNCTION__); } while (0)
;
221
222 r = conf_files_list(&files, ".conf", NULL((void*)0), 0, dir, NULL((void*)0));
223 if (r < 0)
224 return log_error_errno(r, "Failed to list files in \"%s\": %m", dir)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 224, __func__, "Failed to list files in \"%s\": %m"
, dir) : -abs(_e); })
;
225
226 STRV_FOREACH(f, files)for ((f) = (files); (f) && *(f); (f)++) {
227 if (!GREEDY_REALLOC0(array, n_allocated, n + 1)greedy_realloc0((void**) &(array), &(n_allocated), (n
+ 1), sizeof((array)[0]))
)
228 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bootspec.c"
, 228, __func__)
;
229
230 r = boot_entry_load(*f, array + n);
231 if (r < 0)
232 continue;
233
234 n++;
235 }
236
237 qsort_safe(array, n, sizeof(BootEntry), boot_entry_compare);
238
239 *ret_entries = array;
240 *ret_n_entries = n;
241
242 return 0;
243}
244
245static bool_Bool find_nonunique(BootEntry *entries, size_t n_entries, bool_Bool *arr) {
246 size_t i, j;
247 bool_Bool non_unique = false0;
248
249 assert(entries || n_entries == 0)do { if ((__builtin_expect(!!(!(entries || n_entries == 0)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("entries || n_entries == 0"
), "../src/shared/bootspec.c", 249, __PRETTY_FUNCTION__); } while
(0)
;
250 assert(arr || n_entries == 0)do { if ((__builtin_expect(!!(!(arr || n_entries == 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("arr || n_entries == 0"), "../src/shared/bootspec.c"
, 250, __PRETTY_FUNCTION__); } while (0)
;
251
252 for (i = 0; i < n_entries; i++)
253 arr[i] = false0;
254
255 for (i = 0; i < n_entries; i++)
256 for (j = 0; j < n_entries; j++)
257 if (i != j && streq(boot_entry_title(entries + i),(strcmp((boot_entry_title(entries + i)),(boot_entry_title(entries
+ j))) == 0)
258 boot_entry_title(entries + j))(strcmp((boot_entry_title(entries + i)),(boot_entry_title(entries
+ j))) == 0)
)
259 non_unique = arr[i] = arr[j] = true1;
260
261 return non_unique;
262}
263
264static int boot_entries_uniquify(BootEntry *entries, size_t n_entries) {
265 char *s;
266 size_t i;
267 int r;
268 bool_Bool arr[n_entries];
269
270 assert(entries || n_entries == 0)do { if ((__builtin_expect(!!(!(entries || n_entries == 0)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("entries || n_entries == 0"
), "../src/shared/bootspec.c", 270, __PRETTY_FUNCTION__); } while
(0)
;
271
272 /* Find _all_ non-unique titles */
273 if (!find_nonunique(entries, n_entries, arr))
274 return 0;
275
276 /* Add version to non-unique titles */
277 for (i = 0; i < n_entries; i++)
278 if (arr[i] && entries[i].version) {
279 r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].version);
280 if (r < 0)
281 return -ENOMEM12;
282
283 free_and_replace(entries[i].show_title, s)({ free(entries[i].show_title); (entries[i].show_title) = (s)
; (s) = ((void*)0); 0; })
;
284 }
285
286 if (!find_nonunique(entries, n_entries, arr))
287 return 0;
288
289 /* Add machine-id to non-unique titles */
290 for (i = 0; i < n_entries; i++)
291 if (arr[i] && entries[i].machine_id) {
292 r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].machine_id);
293 if (r < 0)
294 return -ENOMEM12;
295
296 free_and_replace(entries[i].show_title, s)({ free(entries[i].show_title); (entries[i].show_title) = (s)
; (s) = ((void*)0); 0; })
;
297 }
298
299 if (!find_nonunique(entries, n_entries, arr))
300 return 0;
301
302 /* Add file name to non-unique titles */
303 for (i = 0; i < n_entries; i++)
304 if (arr[i]) {
305 r = asprintf(&s, "%s (%s)", boot_entry_title(entries + i), entries[i].filename);
306 if (r < 0)
307 return -ENOMEM12;
308
309 free_and_replace(entries[i].show_title, s)({ free(entries[i].show_title); (entries[i].show_title) = (s)
; (s) = ((void*)0); 0; })
;
310 }
311
312 return 0;
313}
314
315static int boot_entries_select_default(const BootConfig *config) {
316 int i;
317
318 assert(config)do { if ((__builtin_expect(!!(!(config)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("config"), "../src/shared/bootspec.c", 318
, __PRETTY_FUNCTION__); } while (0)
;
319
320 if (config->entry_oneshot)
321 for (i = config->n_entries - 1; i >= 0; i--)
322 if (streq(config->entry_oneshot, config->entries[i].filename)(strcmp((config->entry_oneshot),(config->entries[i].filename
)) == 0)
) {
323 log_debug("Found default: filename \"%s\" is matched by LoaderEntryOneShot",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 324, __func__, "Found default: filename \"%s\" is matched by LoaderEntryOneShot"
, config->entries[i].filename) : -abs(_e); })
324 config->entries[i].filename)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 324, __func__, "Found default: filename \"%s\" is matched by LoaderEntryOneShot"
, config->entries[i].filename) : -abs(_e); })
;
325 return i;
326 }
327
328 if (config->entry_default)
329 for (i = config->n_entries - 1; i >= 0; i--)
330 if (streq(config->entry_default, config->entries[i].filename)(strcmp((config->entry_default),(config->entries[i].filename
)) == 0)
) {
331 log_debug("Found default: filename \"%s\" is matched by LoaderEntryDefault",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 332, __func__, "Found default: filename \"%s\" is matched by LoaderEntryDefault"
, config->entries[i].filename) : -abs(_e); })
332 config->entries[i].filename)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 332, __func__, "Found default: filename \"%s\" is matched by LoaderEntryDefault"
, config->entries[i].filename) : -abs(_e); })
;
333 return i;
334 }
335
336 if (config->default_pattern)
337 for (i = config->n_entries - 1; i >= 0; i--)
338 if (fnmatch(config->default_pattern, config->entries[i].filename, FNM_CASEFOLD(1 << 4)) == 0) {
339 log_debug("Found default: filename \"%s\" is matched by pattern \"%s\"",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 340, __func__, "Found default: filename \"%s\" is matched by pattern \"%s\""
, config->entries[i].filename, config->default_pattern)
: -abs(_e); })
340 config->entries[i].filename, config->default_pattern)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 340, __func__, "Found default: filename \"%s\" is matched by pattern \"%s\""
, config->entries[i].filename, config->default_pattern)
: -abs(_e); })
;
341 return i;
342 }
343
344 if (config->n_entries > 0)
345 log_debug("Found default: last entry \"%s\"", config->entries[config->n_entries - 1].filename)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 345, __func__, "Found default: last entry \"%s\""
, config->entries[config->n_entries - 1].filename) : -abs
(_e); })
;
346 else
347 log_debug("Found no default boot entry :(")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 347, __func__, "Found no default boot entry :("
) : -abs(_e); })
;
348
349 return config->n_entries - 1; /* -1 means "no default" */
350}
351
352int boot_entries_load_config(const char *esp_path, BootConfig *config) {
353 const char *p;
354 int r;
355
356 assert(esp_path)do { if ((__builtin_expect(!!(!(esp_path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("esp_path"), "../src/shared/bootspec.c",
356, __PRETTY_FUNCTION__); } while (0)
;
357 assert(config)do { if ((__builtin_expect(!!(!(config)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("config"), "../src/shared/bootspec.c", 357
, __PRETTY_FUNCTION__); } while (0)
;
358
359 p = strjoina(esp_path, "/loader/loader.conf")({ const char *_appendees_[] = { esp_path, "/loader/loader.conf"
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
360 r = boot_loader_read_conf(p, config);
361 if (r < 0)
362 return log_error_errno(r, "Failed to read boot config from \"%s\": %m", p)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 362, __func__, "Failed to read boot config from \"%s\": %m"
, p) : -abs(_e); })
;
363
364 p = strjoina(esp_path, "/loader/entries")({ const char *_appendees_[] = { esp_path, "/loader/entries" }
; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0
; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
365 r = boot_entries_find(p, &config->entries, &config->n_entries);
366 if (r < 0)
367 return log_error_errno(r, "Failed to read boot entries from \"%s\": %m", p)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 367, __func__, "Failed to read boot entries from \"%s\": %m"
, p) : -abs(_e); })
;
368
369 r = boot_entries_uniquify(config->entries, config->n_entries);
370 if (r < 0)
371 return log_error_errno(r, "Failed to uniquify boot entries: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 371, __func__, "Failed to uniquify boot entries: %m"
) : -abs(_e); })
;
372
373 r = efi_get_variable_string(EFI_VENDOR_LOADER((const sd_id128_t) { .bytes = { 0x4a, 0x67, 0xb0, 0x82, 0x0a
, 0x4c, 0x41, 0xcf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c,
0x4f }})
, "LoaderEntryOneShot", &config->entry_oneshot);
374 if (r < 0 && r != -ENOENT2)
375 return log_error_errno(r, "Failed to read EFI var \"LoaderEntryOneShot\": %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 375, __func__, "Failed to read EFI var \"LoaderEntryOneShot\": %m"
) : -abs(_e); })
;
376
377 r = efi_get_variable_string(EFI_VENDOR_LOADER((const sd_id128_t) { .bytes = { 0x4a, 0x67, 0xb0, 0x82, 0x0a
, 0x4c, 0x41, 0xcf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c,
0x4f }})
, "LoaderEntryDefault", &config->entry_default);
378 if (r < 0 && r != -ENOENT2)
379 return log_error_errno(r, "Failed to read EFI var \"LoaderEntryDefault\": %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 379, __func__, "Failed to read EFI var \"LoaderEntryDefault\": %m"
) : -abs(_e); })
;
380
381 config->default_entry = boot_entries_select_default(config);
382 return 0;
383}
384
385/********************************************************************************/
386
387static int verify_esp(
388 const char *p,
389 bool_Bool searching,
390 bool_Bool unprivileged_mode,
391 uint32_t *ret_part,
392 uint64_t *ret_pstart,
393 uint64_t *ret_psize,
394 sd_id128_t *ret_uuid) {
395#if HAVE_BLKID1
396 _cleanup_(blkid_free_probep)__attribute__((cleanup(blkid_free_probep))) blkid_probe b = NULL((void*)0);
397 char t[DEV_NUM_PATH_MAX((sizeof("""/dev/block/""") - 1) + (2+(sizeof(dev_t) <= 1 ?
3 : sizeof(dev_t) <= 2 ? 5 : sizeof(dev_t) <= 4 ? 10 :
sizeof(dev_t) <= 8 ? 20 : sizeof(int[-2*(sizeof(dev_t) >
8)]))) + 1 + (2+(sizeof(dev_t) <= 1 ? 3 : sizeof(dev_t) <=
2 ? 5 : sizeof(dev_t) <= 4 ? 10 : sizeof(dev_t) <= 8 ?
20 : sizeof(int[-2*(sizeof(dev_t) > 8)]))))
];
398 const char *v;
399#endif
400 uint64_t pstart = 0, psize = 0;
401 struct stat st, st2;
402 const char *t2;
403 struct statfs sfs;
404 sd_id128_t uuid = SD_ID128_NULL((const sd_id128_t) { .qwords = { 0, 0 }});
405 uint32_t part = 0;
406 int r;
407
408 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/shared/bootspec.c", 408, __PRETTY_FUNCTION__
); } while (0)
;
409
410 /* Non-root user can only check the status, so if an error occured in the following, it does not cause any
411 * issues. Let's also, silence the error messages. */
412
413 if (statfs(p, &sfs) < 0) {
414 /* If we are searching for the mount point, don't generate a log message if we can't find the path */
415 if (errno(*__errno_location ()) == ENOENT2 && searching)
416 return -ENOENT2;
417
418 return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 419, __func__
, "Failed to check file system type of \"%s\": %m", p) : -abs
(_e); })
419 "Failed to check file system type of \"%s\": %m", p)({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 419, __func__
, "Failed to check file system type of \"%s\": %m", p) : -abs
(_e); })
;
420 }
421
422 if (!F_TYPE_EQUAL(sfs.f_type, MSDOS_SUPER_MAGIC)(sfs.f_type == (typeof(sfs.f_type)) 0x4d44)) {
423 if (searching)
424 return -EADDRNOTAVAIL99;
425
426 log_error("File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 426, __func__, "File system \"%s\" is not a FAT EFI System Partition (ESP) file system."
, p) : -abs(_e); })
;
427 return -ENODEV19;
428 }
429
430 if (stat(p, &st) < 0)
431 return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 432, __func__
, "Failed to determine block device node of \"%s\": %m", p) :
-abs(_e); })
432 "Failed to determine block device node of \"%s\": %m", p)({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 432, __func__
, "Failed to determine block device node of \"%s\": %m", p) :
-abs(_e); })
;
433
434 if (major(st.st_dev)gnu_dev_major (st.st_dev) == 0) {
435 log_error("Block device node of %p is invalid.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 435, __func__, "Block device node of %p is invalid."
, p) : -abs(_e); })
;
436 return -ENODEV19;
437 }
438
439 t2 = strjoina(p, "/..")({ const char *_appendees_[] = { p, "/.." }; char *_d_, *_p_;
size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
440 r = stat(t2, &st2);
441 if (r < 0)
442 return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 443, __func__
, "Failed to determine block device node of parent of \"%s\": %m"
, p) : -abs(_e); })
443 "Failed to determine block device node of parent of \"%s\": %m", p)({ int _level = ((unprivileged_mode && (*__errno_location
()) == 13 ? 7 : 3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 443, __func__
, "Failed to determine block device node of parent of \"%s\": %m"
, p) : -abs(_e); })
;
444
445 if (st.st_dev == st2.st_dev) {
446 log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 446, __func__, "Directory \"%s\" is not the root of the EFI System Partition (ESP) file system."
, p) : -abs(_e); })
;
447 return -ENODEV19;
448 }
449
450 /* In a container we don't have access to block devices, skip this part of the verification, we trust the
451 * container manager set everything up correctly on its own. Also skip the following verification for non-root user. */
452 if (detect_container() > 0 || unprivileged_mode)
453 goto finish;
454
455#if HAVE_BLKID1
456 xsprintf_dev_num_path(t, "block", st.st_dev)do { if ((__builtin_expect(!!(!(((size_t) snprintf(t, __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(t), typeof(&*(t))), sizeof(t)/sizeof((t)[0]), ((void)0))
), "/dev/%s/%u:%u", "block", gnu_dev_major (st.st_dev), gnu_dev_minor
(st.st_dev)) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(t), typeof(&*(t))), sizeof(t)/sizeof((t)[0]), ((void
)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("xsprintf: "
"t" "[] must be big enough"), "../src/shared/bootspec.c", 456
, __PRETTY_FUNCTION__); } while (0)
;
457 errno(*__errno_location ()) = 0;
458 b = blkid_new_probe_from_filename(t);
459 if (!b)
460 return log_error_errno(errno ?: ENOMEM, "Failed to open file system \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 12)),
_realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm
) >= ((_level) & 0x07)) ? log_internal_realm(((_realm)
<< 10 | (_level)), _e, "../src/shared/bootspec.c", 460
, __func__, "Failed to open file system \"%s\": %m", p) : -abs
(_e); })
;
461
462 blkid_probe_enable_superblocks(b, 1);
463 blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE(1 << 5));
464 blkid_probe_enable_partitions(b, 1);
465 blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS(1 << 2));
466
467 errno(*__errno_location ()) = 0;
468 r = blkid_do_safeprobe(b);
469 if (r == -2) {
470 log_error("File system \"%s\" is ambiguous.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 470, __func__, "File system \"%s\" is ambiguous."
, p) : -abs(_e); })
;
471 return -ENODEV19;
472 } else if (r == 1) {
473 log_error("File system \"%s\" does not contain a label.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 473, __func__, "File system \"%s\" does not contain a label."
, p) : -abs(_e); })
;
474 return -ENODEV19;
475 } else if (r != 0)
476 return log_error_errno(errno ?: EIO, "Failed to probe file system \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 476, __func__
, "Failed to probe file system \"%s\": %m", p) : -abs(_e); })
;
477
478 errno(*__errno_location ()) = 0;
479 r = blkid_probe_lookup_value(b, "TYPE", &v, NULL((void*)0));
480 if (r != 0)
481 return log_error_errno(errno ?: EIO, "Failed to probe file system type \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 481, __func__
, "Failed to probe file system type \"%s\": %m", p) : -abs(_e
); })
;
482 if (!streq(v, "vfat")(strcmp((v),("vfat")) == 0)) {
483 log_error("File system \"%s\" is not FAT.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 483, __func__, "File system \"%s\" is not FAT."
, p) : -abs(_e); })
;
484 return -ENODEV19;
485 }
486
487 errno(*__errno_location ()) = 0;
488 r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL((void*)0));
489 if (r != 0)
490 return log_error_errno(errno ?: EIO, "Failed to probe partition scheme \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 490, __func__
, "Failed to probe partition scheme \"%s\": %m", p) : -abs(_e
); })
;
491 if (!streq(v, "gpt")(strcmp((v),("gpt")) == 0)) {
492 log_error("File system \"%s\" is not on a GPT partition table.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 492, __func__, "File system \"%s\" is not on a GPT partition table."
, p) : -abs(_e); })
;
493 return -ENODEV19;
494 }
495
496 errno(*__errno_location ()) = 0;
497 r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL((void*)0));
498 if (r != 0)
499 return log_error_errno(errno ?: EIO, "Failed to probe partition type UUID \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 499, __func__
, "Failed to probe partition type UUID \"%s\": %m", p) : -abs
(_e); })
;
500 if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")(strcmp((v),("c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) == 0)) {
501 log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 501, __func__, "File system \"%s\" has wrong type for an EFI System Partition (ESP)."
, p) : -abs(_e); })
;
502 return -ENODEV19;
503 }
504
505 errno(*__errno_location ()) = 0;
506 r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL((void*)0));
507 if (r != 0)
508 return log_error_errno(errno ?: EIO, "Failed to probe partition entry UUID \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 508, __func__
, "Failed to probe partition entry UUID \"%s\": %m", p) : -abs
(_e); })
;
509 r = sd_id128_from_string(v, &uuid);
510 if (r < 0) {
511 log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 511, __func__, "Partition \"%s\" has invalid UUID \"%s\"."
, p, v) : -abs(_e); })
;
512 return -EIO5;
513 }
514
515 errno(*__errno_location ()) = 0;
516 r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL((void*)0));
517 if (r != 0)
518 return log_error_errno(errno ?: EIO, "Failed to probe partition number \"%s\": m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 518, __func__
, "Failed to probe partition number \"%s\": m", p) : -abs(_e)
; })
;
519 r = safe_atou32(v, &part);
520 if (r < 0)
521 return log_error_errno(r, "Failed to parse PART_ENTRY_NUMBER field.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 521, __func__, "Failed to parse PART_ENTRY_NUMBER field."
) : -abs(_e); })
;
522
523 errno(*__errno_location ()) = 0;
524 r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL((void*)0));
525 if (r != 0)
526 return log_error_errno(errno ?: EIO, "Failed to probe partition offset \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 526, __func__
, "Failed to probe partition offset \"%s\": %m", p) : -abs(_e
); })
;
527 r = safe_atou64(v, &pstart);
528 if (r < 0)
529 return log_error_errno(r, "Failed to parse PART_ENTRY_OFFSET field.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 529, __func__, "Failed to parse PART_ENTRY_OFFSET field."
) : -abs(_e); })
;
530
531 errno(*__errno_location ()) = 0;
532 r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL((void*)0));
533 if (r != 0)
534 return log_error_errno(errno ?: EIO, "Failed to probe partition size \"%s\": %m", p)({ int _level = ((3)), _e = (((*__errno_location ()) ?: 5)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bootspec.c", 534, __func__
, "Failed to probe partition size \"%s\": %m", p) : -abs(_e);
})
;
535 r = safe_atou64(v, &psize);
536 if (r < 0)
537 return log_error_errno(r, "Failed to parse PART_ENTRY_SIZE field.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bootspec.c", 537, __func__, "Failed to parse PART_ENTRY_SIZE field."
) : -abs(_e); })
;
538#endif
539
540finish:
541 if (ret_part)
542 *ret_part = part;
543 if (ret_pstart)
544 *ret_pstart = pstart;
545 if (ret_psize)
546 *ret_psize = psize;
547 if (ret_uuid)
548 *ret_uuid = uuid;
549
550 return 0;
551}
552
553int find_esp_and_warn(
554 const char *path,
555 bool_Bool unprivileged_mode,
556 char **ret_path,
557 uint32_t *ret_part,
558 uint64_t *ret_pstart,
559 uint64_t *ret_psize,
560 sd_id128_t *ret_uuid) {
561
562 int r;
563
564 /* This logs about all errors except:
565 *
566 * -ENOKEY → when we can't find the partition
567 * -EACCESS → when unprivileged_mode is true, and we can't access something
568 */
569
570 if (path) {
571 r = verify_esp(path, false0, unprivileged_mode, ret_part, ret_pstart, ret_psize, ret_uuid);
572 if (r < 0)
573 return r;
574
575 goto found;
576 }
577
578 FOREACH_STRING(path, "/efi", "/boot", "/boot/efi")for (char **_l = ({ char **_ll = ((char**) ((const char*[]) {
"/efi", "/boot", "/boot/efi", ((void*)0) })); path = _ll ? _ll
[0] : ((void*)0); _ll; }); _l && *_l; path = ({ _l ++
; _l[0]; }))
{
579
580 r = verify_esp(path, true1, unprivileged_mode, ret_part, ret_pstart, ret_psize, ret_uuid);
581 if (r >= 0)
582 goto found;
583 if (!IN_SET(r, -ENOENT, -EADDRNOTAVAIL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-2, -99})/sizeof(int)]; switch(r) { case
-2: case -99: _found = 1; break; default: break; } _found; }
)
) /* This one is not it */
584 return r;
585 }
586
587 /* No logging here */
588 return -ENOKEY126;
589
590found:
591 if (ret_path) {
592 char *c;
593
594 c = strdup(path);
595 if (!c)
596 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bootspec.c"
, 596, __func__)
;
597
598 *ret_path = c;
599 }
600
601 return 0;
602}