File: | build-scan/../src/shared/bootspec.c |
Warning: | line 119, column 9 Value stored to 'tmp' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
23 | void 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 | |
39 | int 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 | |
123 | void 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 | |
142 | int 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 | |
205 | static 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 | |
211 | int 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 | |
245 | static 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 | |
264 | static 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 | |
315 | static 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 | |
352 | int 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 | |
387 | static 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 | |
540 | finish: |
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 | |
553 | int 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 | |
590 | found: |
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 | } |