find-esp: rework ESP/XBOOTLDR discovery logic around returning an O_PATH fd (#41658)
Let O_PATH reign, let's make ESP/XBOOTLDR discovery return them directly. Split out of #41543 but makes a ton of sense anyway and on its own.
This commit is contained in:
+2
-2
@@ -1098,7 +1098,7 @@ int chase_and_unlink(const char *path, const char *root, ChaseFlags chase_flags,
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_SOCKET|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_DIRECTORY|CHASE_EXTRACT_FILENAME|CHASE_MKDIR_0755)));
|
||||
|
||||
fd = chase_and_open(path, root, chase_flags|CHASE_PARENT|CHASE_NOFOLLOW, O_PATH|O_DIRECTORY|O_CLOEXEC, &p);
|
||||
if (fd < 0)
|
||||
@@ -1312,7 +1312,7 @@ int chase_and_unlinkat(int dir_fd, const char *path, ChaseFlags chase_flags, int
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_SOCKET|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_DIRECTORY|CHASE_EXTRACT_FILENAME|CHASE_MKDIR_0755)));
|
||||
|
||||
fd = chase_and_openat(dir_fd, path, chase_flags|CHASE_PARENT|CHASE_NOFOLLOW, O_PATH|O_DIRECTORY|O_CLOEXEC, &p);
|
||||
if (fd < 0)
|
||||
|
||||
@@ -115,6 +115,7 @@ static int acquire_path(void) {
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&esp_path,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -128,6 +129,7 @@ static int acquire_path(void) {
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&xbootldr_path,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r < 0 && r != -ENOKEY)
|
||||
|
||||
@@ -93,6 +93,7 @@ int verb_cleanup(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -103,6 +104,7 @@ int verb_cleanup(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r < 0)
|
||||
|
||||
@@ -163,6 +163,7 @@ static int install_context_from_cmdline(
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
b.graceful,
|
||||
&b.esp_fd,
|
||||
&b.esp_part,
|
||||
&b.esp_pstart,
|
||||
&b.esp_psize,
|
||||
@@ -189,6 +190,7 @@ static int install_context_from_cmdline(
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ false,
|
||||
&b.xbootldr_fd,
|
||||
/* ret_uuid= */ NULL,
|
||||
/* ret_devid= */ NULL);
|
||||
if (r < 0)
|
||||
@@ -213,55 +215,16 @@ static int install_context_from_cmdline(
|
||||
return !!ret->esp_path; /* return positive if we found an ESP */
|
||||
}
|
||||
|
||||
static int acquire_esp_fd(InstallContext *c) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->esp_fd >= 0)
|
||||
return c->esp_fd;
|
||||
|
||||
assert(c->esp_path);
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
r = chaseat(c->root_fd,
|
||||
c->esp_path,
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_TRIGGER_AUTOFS|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
&c->esp_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open ESP '%s': %m", j);
|
||||
|
||||
return c->esp_fd;
|
||||
}
|
||||
|
||||
static int acquire_dollar_boot_fd(InstallContext *c) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->xbootldr_fd >= 0)
|
||||
return c->xbootldr_fd;
|
||||
|
||||
if (!c->xbootldr_path)
|
||||
return acquire_esp_fd(c);
|
||||
if (c->esp_fd >= 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->xbootldr_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
r = chaseat(c->root_fd,
|
||||
c->xbootldr_path,
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_TRIGGER_AUTOFS|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
&c->xbootldr_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open XBOOTLDR '%s': %m", j);
|
||||
|
||||
return c->xbootldr_fd;
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Cannot access $BOOT, as neither ESP nor XBOOTLDR have been found.");
|
||||
}
|
||||
|
||||
static const char* dollar_boot_path(InstallContext *c) {
|
||||
@@ -639,9 +602,8 @@ static int update_efi_boot_binaries(
|
||||
assert(c);
|
||||
assert(source_path);
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
@@ -649,7 +611,7 @@ static int update_efi_boot_binaries(
|
||||
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
r = chase_and_opendirat(
|
||||
esp_fd,
|
||||
c->esp_fd,
|
||||
"/EFI/BOOT",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
@@ -738,16 +700,15 @@ static int copy_one_file(
|
||||
return log_error_errno(source_fd, "Failed to resolve path '%s': %m", sp);
|
||||
}
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_close_ int dest_parent_fd = -EBADF;
|
||||
r = chaseat(esp_fd,
|
||||
r = chaseat(c->esp_fd,
|
||||
"/EFI/systemd",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
@@ -778,7 +739,7 @@ static int copy_one_file(
|
||||
ascii_strupper(boot_dot_efi);
|
||||
|
||||
_cleanup_close_ int default_dest_parent_fd = -EBADF;
|
||||
r = chaseat(esp_fd,
|
||||
r = chaseat(c->esp_fd,
|
||||
"/EFI/BOOT",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
@@ -875,16 +836,15 @@ static int install_loader_config(InstallContext *c) {
|
||||
assert(c);
|
||||
assert(c->make_entry_directory >= 0);
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_close_ int loader_dir_fd = -EBADF;
|
||||
r = chaseat(esp_fd,
|
||||
r = chaseat(c->esp_fd,
|
||||
"loader",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
@@ -1071,16 +1031,15 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert X.509 certificate to DER: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_close_ int keys_fd = -EBADF;
|
||||
r = chaseat(esp_fd,
|
||||
r = chaseat(c->esp_fd,
|
||||
"loader/keys/auto",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
/* ret_path= */ NULL,
|
||||
@@ -1385,16 +1344,15 @@ static int install_variables(
|
||||
|
||||
assert(c);
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
r = chase_and_accessat(
|
||||
esp_fd,
|
||||
c->esp_fd,
|
||||
path,
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MUST_BE_REGULAR,
|
||||
F_OK,
|
||||
@@ -1422,7 +1380,7 @@ static int install_variables(
|
||||
if (c->operation == INSTALL_NEW || !existing) {
|
||||
_cleanup_free_ char *description = NULL;
|
||||
|
||||
r = pick_efi_boot_option_description(esp_fd, &description);
|
||||
r = pick_efi_boot_option_description(c->esp_fd, &description);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1474,12 +1432,11 @@ static int are_we_installed(InstallContext *c) {
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_close_ int fd = chase_and_openat(
|
||||
esp_fd,
|
||||
c->esp_fd,
|
||||
"/EFI/systemd",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MUST_BE_DIRECTORY,
|
||||
O_RDONLY|O_CLOEXEC|O_DIRECTORY,
|
||||
@@ -1582,9 +1539,8 @@ static int run_install(InstallContext *c) {
|
||||
|
||||
const char *arch = arg_arch_all ? "" : get_efi_arch();
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c->root, c->esp_path);
|
||||
if (!j)
|
||||
@@ -1604,7 +1560,7 @@ static int run_install(InstallContext *c) {
|
||||
* we'll drop-in our files (unless there are newer ones already), but we won't create
|
||||
* the directories for them in the first place. */
|
||||
|
||||
r = create_subdirs(j, esp_fd, esp_subdirs);
|
||||
r = create_subdirs(j, c->esp_fd, esp_subdirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1631,7 +1587,7 @@ static int run_install(InstallContext *c) {
|
||||
return r;
|
||||
|
||||
if (arg_install_random_seed && !c->root) {
|
||||
r = install_random_seed(c->esp_path);
|
||||
r = install_random_seed(c->esp_path, c->esp_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -1689,9 +1645,8 @@ static int remove_boot_efi(InstallContext *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
int esp_fd = acquire_esp_fd(c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c->esp_fd < 0)
|
||||
return c->esp_fd;
|
||||
|
||||
_cleanup_free_ char *w = path_join(c->root, c->esp_path);
|
||||
if (!w)
|
||||
@@ -1700,7 +1655,7 @@ static int remove_boot_efi(InstallContext *c) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
r = chase_and_opendirat(
|
||||
esp_fd,
|
||||
c->esp_fd,
|
||||
"/EFI/BOOT",
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_MUST_BE_DIRECTORY,
|
||||
&p,
|
||||
@@ -1898,15 +1853,14 @@ int verb_remove(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
int esp_fd = acquire_esp_fd(&c);
|
||||
if (esp_fd < 0)
|
||||
return esp_fd;
|
||||
if (c.esp_fd < 0)
|
||||
return c.esp_fd;
|
||||
|
||||
_cleanup_free_ char *j = path_join(c.root, c.esp_path);
|
||||
if (!j)
|
||||
return log_oom();
|
||||
|
||||
int dollar_boot_fd = acquire_dollar_boot_fd(&c); /* this will initialize .xbootldr_fd */
|
||||
int dollar_boot_fd = acquire_dollar_boot_fd(&c);
|
||||
if (dollar_boot_fd < 0)
|
||||
return dollar_boot_fd;
|
||||
|
||||
@@ -1915,23 +1869,23 @@ int verb_remove(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return log_oom();
|
||||
|
||||
r = remove_binaries(&c);
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, "/loader/loader.conf", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, "/loader/random-seed", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, "/loader/entries.srel", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, "/loader/loader.conf", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, "/loader/random-seed", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, "/loader/entries.srel", S_IFREG));
|
||||
|
||||
FOREACH_STRING(db, "PK.auth", "KEK.auth", "db.auth") {
|
||||
_cleanup_free_ char *p = path_join("/loader/keys/auto", db);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, p, S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, p, S_IFREG));
|
||||
}
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, "/loader/keys/auto", S_IFDIR));
|
||||
RET_GATHER(r, unlink_inode(j, esp_fd, "/loader/entries.srel", S_IFREG));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, "/loader/keys/auto", S_IFDIR));
|
||||
RET_GATHER(r, unlink_inode(j, c.esp_fd, "/loader/entries.srel", S_IFREG));
|
||||
|
||||
RET_GATHER(r, remove_subdirs(j, esp_fd, esp_subdirs));
|
||||
RET_GATHER(r, remove_subdirs(j, esp_fd, dollar_boot_subdirs));
|
||||
RET_GATHER(r, remove_entry_directory(&c, j, esp_fd));
|
||||
RET_GATHER(r, remove_subdirs(j, c.esp_fd, esp_subdirs));
|
||||
RET_GATHER(r, remove_subdirs(j, c.esp_fd, dollar_boot_subdirs));
|
||||
RET_GATHER(r, remove_entry_directory(&c, j, c.esp_fd));
|
||||
|
||||
if (c.xbootldr_fd >= 0) {
|
||||
/* Remove a subset of these also from the XBOOTLDR partition if it exists */
|
||||
@@ -2066,6 +2020,7 @@ int vl_method_install(
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.esp_path,
|
||||
&p.context.esp_fd,
|
||||
&p.context.esp_part,
|
||||
&p.context.esp_pstart,
|
||||
&p.context.esp_psize,
|
||||
@@ -2080,7 +2035,8 @@ int vl_method_install(
|
||||
p.context.root_fd,
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&p.context.xbootldr_path);
|
||||
&p.context.xbootldr_path,
|
||||
&p.context.xbootldr_fd);
|
||||
if (r == -ENOKEY)
|
||||
log_debug_errno(r, "Didn't find an XBOOTLDR partition, using ESP as $BOOT.");
|
||||
else if (r < 0)
|
||||
|
||||
@@ -111,8 +111,8 @@ static int set_system_token(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int install_random_seed(const char *esp) {
|
||||
_cleanup_close_ int esp_fd = -EBADF, loader_dir_fd = -EBADF, fd = -EBADF;
|
||||
int install_random_seed(const char *esp, int esp_fd) {
|
||||
_cleanup_close_ int loader_dir_fd = -EBADF, fd = -EBADF;
|
||||
_cleanup_free_ char *tmp = NULL;
|
||||
uint8_t buffer[RANDOM_EFI_SEED_SIZE];
|
||||
struct sha256_ctx hash_state;
|
||||
@@ -120,16 +120,13 @@ int install_random_seed(const char *esp) {
|
||||
int r;
|
||||
|
||||
assert(esp);
|
||||
assert(esp_fd >= 0);
|
||||
|
||||
assert_cc(RANDOM_EFI_SEED_SIZE == SHA256_DIGEST_SIZE);
|
||||
|
||||
if (!arg_install_random_seed)
|
||||
return 0;
|
||||
|
||||
esp_fd = open(esp, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
|
||||
if (esp_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open ESP directory '%s': %m", esp);
|
||||
|
||||
(void) random_seed_verify_permissions(esp_fd, S_IFDIR);
|
||||
|
||||
loader_dir_fd = open_mkdir_at(esp_fd, "loader", O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOFOLLOW, 0775);
|
||||
@@ -204,7 +201,8 @@ int install_random_seed(const char *esp) {
|
||||
int verb_random_seed(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int r;
|
||||
|
||||
r = find_esp_and_warn(arg_root, arg_esp_path, /* unprivileged_mode= */ false, &arg_esp_path);
|
||||
_cleanup_close_ int esp_fd = -EBADF;
|
||||
r = find_esp_and_warn(arg_root, arg_esp_path, /* unprivileged_mode= */ false, &arg_esp_path, &esp_fd);
|
||||
if (r == -ENOKEY) {
|
||||
/* find_esp_and_warn() doesn't warn about ENOKEY, so let's do that on our own */
|
||||
if (arg_graceful() == ARG_GRACEFUL_NO)
|
||||
@@ -216,7 +214,7 @@ int verb_random_seed(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = install_random_seed(arg_esp_path);
|
||||
r = install_random_seed(arg_esp_path, esp_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
int install_random_seed(const char *esp);
|
||||
int install_random_seed(const char *esp, int esp_fd);
|
||||
|
||||
int verb_random_seed(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
|
||||
@@ -334,6 +334,7 @@ int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ -1,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -352,6 +353,7 @@ int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ -1,
|
||||
/* ret_fd= */ NULL,
|
||||
&xbootldr_uuid,
|
||||
&xbootldr_devid);
|
||||
if (arg_print_dollar_boot_path) {
|
||||
@@ -644,13 +646,24 @@ int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
(void) touch_variables();
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, NULL, &esp_devid);
|
||||
r = acquire_esp(/* unprivileged_mode= */ -1,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&esp_devid);
|
||||
if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */
|
||||
return log_error_errno(r, "Failed to determine ESP location: %m");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = acquire_xbootldr(/* unprivileged_mode= */ -1, NULL, &xbootldr_devid);
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ -1,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r == -EACCES)
|
||||
return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
|
||||
if (r < 0)
|
||||
@@ -683,6 +696,7 @@ int vl_method_list_boot_entries(sd_varlink *link, sd_json_variant *parameters, s
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -695,6 +709,7 @@ int vl_method_list_boot_entries(sd_varlink *link, sd_json_variant *parameters, s
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r == -EACCES)
|
||||
|
||||
@@ -205,6 +205,7 @@ int verb_unlink(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -217,6 +218,7 @@ int verb_unlink(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
r = acquire_xbootldr(
|
||||
/* unprivileged_mode= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r == -EACCES)
|
||||
|
||||
+44
-15
@@ -21,6 +21,7 @@
|
||||
#include "efi-loader.h"
|
||||
#include "efivars.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "find-esp.h"
|
||||
#include "format-table.h"
|
||||
#include "image-policy.h"
|
||||
@@ -100,16 +101,16 @@ static const char* const install_source_table[_INSTALL_SOURCE_MAX] = {
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(install_source, InstallSource);
|
||||
|
||||
int acquire_esp(
|
||||
int unprivileged_mode,
|
||||
int acquire_esp(int unprivileged_mode,
|
||||
bool graceful,
|
||||
int *ret_fd,
|
||||
uint32_t *ret_part,
|
||||
uint64_t *ret_pstart,
|
||||
uint64_t *ret_psize,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
char *np;
|
||||
_cleanup_free_ char *np = NULL;
|
||||
int r;
|
||||
|
||||
/* Find the ESP, and log about errors. Note that find_esp_and_warn() will log in all error cases on
|
||||
@@ -118,7 +119,7 @@ int acquire_esp(
|
||||
* we simply eat up the error here, so that --list and --status work too, without noise about
|
||||
* this). */
|
||||
|
||||
r = find_esp_and_warn_full(arg_root, arg_esp_path, unprivileged_mode, &np, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid);
|
||||
r = find_esp_and_warn_full(arg_root, arg_esp_path, unprivileged_mode, &np, ret_fd, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid);
|
||||
if (r == -ENOKEY) {
|
||||
if (graceful)
|
||||
return log_full_errno(arg_quiet ? LOG_DEBUG : LOG_INFO, r,
|
||||
@@ -134,27 +135,44 @@ int acquire_esp(
|
||||
free_and_replace(arg_esp_path, np);
|
||||
log_debug("Using EFI System Partition at %s.", arg_esp_path);
|
||||
|
||||
return 0;
|
||||
return 1; /* for symmetry with acquire_xbootldr() below: found */
|
||||
}
|
||||
|
||||
int acquire_xbootldr(
|
||||
int unprivileged_mode,
|
||||
int *ret_fd,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
char *np;
|
||||
int r;
|
||||
|
||||
r = find_xbootldr_and_warn_full(arg_root, arg_xbootldr_path, unprivileged_mode, &np, ret_uuid, ret_devid);
|
||||
if (r == -ENOKEY || path_equal(np, arg_esp_path)) {
|
||||
log_debug("Didn't find an XBOOTLDR partition, using the ESP as $BOOT.");
|
||||
_cleanup_free_ char *np = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
r = find_xbootldr_and_warn_full(
|
||||
arg_root,
|
||||
arg_xbootldr_path,
|
||||
unprivileged_mode,
|
||||
&np,
|
||||
ret_fd ? &fd : NULL,
|
||||
ret_uuid,
|
||||
ret_devid);
|
||||
if (r == -ENOKEY || (r >= 0 && arg_esp_path && path_equal(np, arg_esp_path))) {
|
||||
|
||||
if (arg_esp_path)
|
||||
log_debug("Didn't find an XBOOTLDR partition, using the ESP as $BOOT.");
|
||||
else
|
||||
log_debug("Found neither an XBOOTLDR partition, nor an ESP.");
|
||||
|
||||
arg_xbootldr_path = mfree(arg_xbootldr_path);
|
||||
|
||||
if (ret_fd)
|
||||
*ret_fd = -EBADF;
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
if (ret_devid)
|
||||
*ret_devid = 0;
|
||||
return 0;
|
||||
|
||||
return 0; /* not found */
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -162,7 +180,10 @@ int acquire_xbootldr(
|
||||
free_and_replace(arg_xbootldr_path, np);
|
||||
log_debug("Using XBOOTLDR partition at %s as $BOOT.", arg_xbootldr_path);
|
||||
|
||||
return 1;
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
|
||||
return 1; /* found */
|
||||
}
|
||||
|
||||
static int print_loader_or_stub_path(void) {
|
||||
@@ -199,9 +220,14 @@ static int print_loader_or_stub_path(void) {
|
||||
}
|
||||
|
||||
sd_id128_t esp_uuid;
|
||||
r = acquire_esp(/* unprivileged_mode= */ false, /* graceful= */ false,
|
||||
/* ret_part= */ NULL, /* ret_pstart= */ NULL, /* ret_psize= */ NULL,
|
||||
&esp_uuid, /* ret_devid= */ NULL);
|
||||
r = acquire_esp(/* unprivileged_mode= */ false,
|
||||
/* graceful= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
&esp_uuid,
|
||||
/* ret_devid= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -211,7 +237,10 @@ static int print_loader_or_stub_path(void) {
|
||||
else if (arg_print_stub_path) { /* In case of the stub, also look for things in the xbootldr partition */
|
||||
sd_id128_t xbootldr_uuid;
|
||||
|
||||
r = acquire_xbootldr(/* unprivileged_mode= */ false, &xbootldr_uuid, /* ret_devid= */ NULL);
|
||||
r = acquire_xbootldr(/* unprivileged_mode= */ false,
|
||||
/* ret_fd= */ NULL,
|
||||
&xbootldr_uuid,
|
||||
/* ret_devid= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ static inline const char* arg_dollar_boot_path(void) {
|
||||
|
||||
GracefulMode arg_graceful(void);
|
||||
|
||||
int acquire_esp(int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int acquire_xbootldr(int unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int acquire_esp(int unprivileged_mode, bool graceful, int *ret_fd, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int acquire_xbootldr(int unprivileged_mode, int *ret_fd, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
|
||||
/* EFI_BOOT_OPTION_DESCRIPTION_MAX sets the maximum length for the boot option description
|
||||
* stored in NVRAM. The UEFI spec does not specify a minimum or maximum length for this
|
||||
|
||||
@@ -570,7 +570,8 @@ static int context_acquire_xbootldr(Context *c) {
|
||||
/* rfd= */ c->rfd,
|
||||
/* path= */ arg_xbootldr_path,
|
||||
/* unprivileged_mode= */ -1,
|
||||
/* ret_path= */ &c->boot_root);
|
||||
/* ret_path= */ &c->boot_root,
|
||||
/* ret_fd= */ NULL);
|
||||
if (r == -ENOKEY) {
|
||||
log_debug_errno(r, "Couldn't find an XBOOTLDR partition.");
|
||||
return 0;
|
||||
@@ -594,7 +595,8 @@ static int context_acquire_esp(Context *c) {
|
||||
/* rfd= */ c->rfd,
|
||||
/* path= */ arg_esp_path,
|
||||
/* unprivileged_mode= */ -1,
|
||||
/* ret_path= */ &c->boot_root);
|
||||
/* ret_path= */ &c->boot_root,
|
||||
/* ret_fd= */ NULL);
|
||||
if (r == -ENOKEY) {
|
||||
log_debug_errno(r, "Couldn't find EFI system partition, ignoring.");
|
||||
return 0;
|
||||
|
||||
@@ -1597,6 +1597,7 @@ int boot_config_load_auto(
|
||||
override_esp_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&esp_where,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_part= */ NULL,
|
||||
/* ret_pstart= */ NULL,
|
||||
/* ret_psize= */ NULL,
|
||||
@@ -1610,6 +1611,7 @@ int boot_config_load_auto(
|
||||
override_xbootldr_path,
|
||||
/* unprivileged_mode= */ false,
|
||||
&xbootldr_where,
|
||||
/* ret_fd= */ NULL,
|
||||
/* ret_uuid= */ NULL,
|
||||
&xbootldr_devid);
|
||||
if (r < 0 && r != -ENOKEY)
|
||||
|
||||
@@ -101,8 +101,7 @@ int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret) {
|
||||
uint64_t id;
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(path);
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
|
||||
|
||||
@@ -54,7 +54,7 @@ static inline int btrfs_get_block_device(const char *path, dev_t *ret) {
|
||||
return btrfs_get_block_device_at(AT_FDCWD, path, ret);
|
||||
}
|
||||
static inline int btrfs_get_block_device_fd(int fd, dev_t *ret) {
|
||||
return btrfs_get_block_device_at(fd, "", ret);
|
||||
return btrfs_get_block_device_at(fd, NULL, ret);
|
||||
}
|
||||
|
||||
int btrfs_defrag_fd(int fd);
|
||||
|
||||
@@ -1709,7 +1709,8 @@ int get_global_boot_credentials_path(char **ret) {
|
||||
/* root= */ NULL,
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&path);
|
||||
&path,
|
||||
/* ret_fd= */ NULL);
|
||||
if (r < 0) {
|
||||
if (r != -ENOKEY)
|
||||
return log_error_errno(r, "Failed to find XBOOTLDR partition: %m");
|
||||
@@ -1718,7 +1719,8 @@ int get_global_boot_credentials_path(char **ret) {
|
||||
/* root= */ NULL,
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&path);
|
||||
&path,
|
||||
/* ret_fd= */ NULL);
|
||||
if (r < 0) {
|
||||
if (r != -ENOKEY)
|
||||
return log_error_errno(r, "Failed to find ESP partition: %m");
|
||||
|
||||
+118
-120
@@ -19,7 +19,6 @@
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "find-esp.h"
|
||||
#include "mount-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "stat-util.h"
|
||||
@@ -260,33 +259,24 @@ static int verify_esp_udev(
|
||||
}
|
||||
|
||||
static int verify_fsroot_dir(
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
int fd,
|
||||
VerifyESPFlags flags,
|
||||
dev_t *ret_dev) {
|
||||
|
||||
bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
|
||||
_cleanup_free_ char *f = NULL;
|
||||
struct statx sx;
|
||||
int r;
|
||||
|
||||
/* Checks if the specified directory is at the root of its file system, and returns device
|
||||
* major/minor of the device, if it is. */
|
||||
|
||||
assert(dir_fd >= 0);
|
||||
assert(path);
|
||||
assert(fd >= 0);
|
||||
|
||||
/* We pass the full path from the root directory file descriptor so we can use it for logging, but
|
||||
* dir_fd points to the parent directory of the final component of the given path, so we extract the
|
||||
* filename and operate on that. */
|
||||
|
||||
r = path_extract_filename(path, &f);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
return log_error_errno(r, "Failed to extract filename of \"%s\": %m", path);
|
||||
|
||||
r = xstatx_full(dir_fd, f,
|
||||
AT_SYMLINK_NOFOLLOW,
|
||||
struct statx sx;
|
||||
r = xstatx_full(fd, /* path= */ NULL,
|
||||
/* statx_flags= */ 0,
|
||||
/* xstatx_flags= */ 0,
|
||||
STATX_TYPE|STATX_INO,
|
||||
/* optional_mask = */ 0,
|
||||
@@ -310,7 +300,7 @@ static int verify_fsroot_dir(
|
||||
return 0;
|
||||
|
||||
if (sx.stx_dev_major == 0) /* Hmm, maybe a btrfs device, and the caller asked for the backing device? Then let's try to get it. */
|
||||
return btrfs_get_block_device_at(dir_fd, strempty(f), ret_dev);
|
||||
return btrfs_get_block_device_fd(fd, ret_dev);
|
||||
|
||||
*ret_dev = makedev(sx.stx_dev_major, sx.stx_dev_minor);
|
||||
return 0;
|
||||
@@ -320,6 +310,7 @@ static int verify_esp(
|
||||
int rfd,
|
||||
const char *path,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
uint32_t *ret_part,
|
||||
uint64_t *ret_pstart,
|
||||
uint64_t *ret_psize,
|
||||
@@ -329,9 +320,6 @@ static int verify_esp(
|
||||
|
||||
bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
dev_t devid = 0;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
@@ -347,87 +335,71 @@ static int verify_esp(
|
||||
/* Non-root user can only check the status, so if an error occurred in the following, it does not cause any
|
||||
* issues. Let's also, silence the error messages. */
|
||||
|
||||
r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT|CHASE_TRIGGER_AUTOFS, &p, &pfd);
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_TRIGGER_AUTOFS, &p, &fd);
|
||||
if (r < 0)
|
||||
return log_full_errno((searching && r == -ENOENT) ||
|
||||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
|
||||
r, "Failed to open parent directory of \"%s\": %m", path);
|
||||
r, "Failed to open directory \"%s\": %m", path);
|
||||
|
||||
if (!FLAGS_SET(flags, VERIFY_ESP_SKIP_FSTYPE_CHECK)) {
|
||||
_cleanup_free_ char *f = NULL;
|
||||
struct statfs sfs;
|
||||
|
||||
r = path_extract_filename(p, &f);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
return log_error_errno(r, "Failed to extract filename of \"%s\": %m", p);
|
||||
|
||||
/* Trigger any automounts so that xstatfsat() operates on the mount instead of the mountpoint
|
||||
* directory. */
|
||||
r = trigger_automount_at(pfd, f);
|
||||
r = fd_is_fs_type(fd, MSDOS_SUPER_MAGIC);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to trigger automount at \"%s\": %m", p);
|
||||
|
||||
r = xstatfsat(pfd, strempty(f), &sfs);
|
||||
if (r < 0)
|
||||
/* If we are searching for the mount point, don't generate a log message if we can't find the path */
|
||||
return log_full_errno((searching && r == -ENOENT) ||
|
||||
(unprivileged_mode && r == -EACCES) ? LOG_DEBUG : LOG_ERR, r,
|
||||
return log_full_errno((unprivileged_mode && r == -EACCES) ? LOG_DEBUG : LOG_ERR, r,
|
||||
"Failed to check file system type of \"%s\": %m", p);
|
||||
|
||||
if (!F_TYPE_EQUAL(sfs.f_type, MSDOS_SUPER_MAGIC))
|
||||
if (!r)
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
|
||||
}
|
||||
|
||||
r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
dev_t devid = 0;
|
||||
r = verify_fsroot_dir(p, fd, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* In a container we don't have access to block devices, skip this part of the verification, we trust
|
||||
* the container manager set everything up correctly on its own. */
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK))
|
||||
goto finish;
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK)) {
|
||||
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).", p);
|
||||
if (ret_part)
|
||||
*ret_part = 0;
|
||||
if (ret_pstart)
|
||||
*ret_pstart = 0;
|
||||
if (ret_psize)
|
||||
*ret_psize = 0;
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
|
||||
/* If we are unprivileged we ask udev for the metadata about the partition. If we are privileged we
|
||||
* use blkid instead. Why? Because this code is called from 'bootctl' which is pretty much an
|
||||
* emergency recovery tool that should also work when udev isn't up (i.e. from the emergency shell),
|
||||
* however blkid can't work if we have no privileges to access block devices directly, which is why
|
||||
* we use udev in that case. */
|
||||
if (unprivileged_mode)
|
||||
r = verify_esp_udev(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
|
||||
else
|
||||
r = verify_esp_blkid(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).", p);
|
||||
|
||||
/* If we are unprivileged we ask udev for the metadata about the partition. If we are privileged we
|
||||
* use blkid instead. Why? Because this code is called from 'bootctl' which is pretty much an
|
||||
* emergency recovery tool that should also work when udev isn't up (i.e. from the emergency shell),
|
||||
* however blkid can't work if we have no privileges to access block devices directly, which is why
|
||||
* we use udev in that case. */
|
||||
if (unprivileged_mode)
|
||||
r = verify_esp_udev(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
|
||||
else
|
||||
r = verify_esp_blkid(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_devid)
|
||||
*ret_devid = devid;
|
||||
|
||||
return 0;
|
||||
|
||||
finish:
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_part)
|
||||
*ret_part = 0;
|
||||
if (ret_pstart)
|
||||
*ret_pstart = 0;
|
||||
if (ret_psize)
|
||||
*ret_psize = 0;
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
if (ret_devid)
|
||||
*ret_devid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_esp_and_warn_at_full(
|
||||
@@ -435,6 +407,7 @@ int find_esp_and_warn_at_full(
|
||||
const char *path,
|
||||
int unprivileged_mode,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
uint32_t *ret_part,
|
||||
uint64_t *ret_pstart,
|
||||
uint64_t *ret_psize,
|
||||
@@ -455,7 +428,7 @@ int find_esp_and_warn_at_full(
|
||||
flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_ESP_CHECKS");
|
||||
|
||||
if (path)
|
||||
return verify_esp(rfd, path, ret_path, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid, flags);
|
||||
return verify_esp(rfd, path, ret_path, ret_fd, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid, flags);
|
||||
|
||||
path = getenv("SYSTEMD_ESP_PATH");
|
||||
if (path) {
|
||||
@@ -484,6 +457,8 @@ int find_esp_and_warn_at_full(
|
||||
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_part)
|
||||
*ret_part = 0;
|
||||
if (ret_pstart)
|
||||
@@ -499,7 +474,15 @@ int find_esp_and_warn_at_full(
|
||||
}
|
||||
|
||||
FOREACH_STRING(dir, "/efi", "/boot", "/boot/efi") {
|
||||
r = verify_esp(rfd, dir, ret_path, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid,
|
||||
r = verify_esp(rfd,
|
||||
dir,
|
||||
ret_path,
|
||||
ret_fd,
|
||||
ret_part,
|
||||
ret_pstart,
|
||||
ret_psize,
|
||||
ret_uuid,
|
||||
ret_devid,
|
||||
flags | VERIFY_ESP_SEARCHING);
|
||||
if (r >= 0)
|
||||
return 0;
|
||||
@@ -516,20 +499,16 @@ int find_esp_and_warn_full(
|
||||
const char *path,
|
||||
int unprivileged_mode,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
uint32_t *ret_part,
|
||||
uint64_t *ret_pstart,
|
||||
uint64_t *ret_psize,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
uint32_t part;
|
||||
uint64_t pstart, psize;
|
||||
sd_id128_t uuid;
|
||||
dev_t devid;
|
||||
int r;
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
if (empty_or_root(root))
|
||||
rfd = XAT_FDROOT;
|
||||
else {
|
||||
@@ -538,11 +517,18 @@ int find_esp_and_warn_full(
|
||||
return -errno;
|
||||
}
|
||||
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
uint32_t part;
|
||||
uint64_t pstart, psize;
|
||||
sd_id128_t uuid;
|
||||
dev_t devid;
|
||||
r = find_esp_and_warn_at_full(
|
||||
rfd,
|
||||
path,
|
||||
unprivileged_mode,
|
||||
ret_path ? &p : NULL,
|
||||
ret_fd ? &fd : NULL,
|
||||
ret_part ? &part : NULL,
|
||||
ret_pstart ? &pstart : NULL,
|
||||
ret_psize ? &psize : NULL,
|
||||
@@ -556,6 +542,8 @@ int find_esp_and_warn_full(
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_part)
|
||||
*ret_part = part;
|
||||
if (ret_pstart)
|
||||
@@ -734,64 +722,59 @@ static int verify_xbootldr(
|
||||
const char *path,
|
||||
VerifyESPFlags flags,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
|
||||
dev_t devid = 0;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || IN_SET(rfd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(path);
|
||||
|
||||
r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT|CHASE_TRIGGER_AUTOFS, &p, &pfd);
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_TRIGGER_AUTOFS, &p, &fd);
|
||||
if (r < 0)
|
||||
return log_full_errno((searching && r == -ENOENT) ||
|
||||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
|
||||
r, "Failed to open parent directory of \"%s\": %m", path);
|
||||
r, "Failed to open directory \"%s\": %m", path);
|
||||
|
||||
r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
dev_t devid = 0;
|
||||
r = verify_fsroot_dir(p, fd, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK))
|
||||
goto finish;
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK)) {
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
} else {
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).%s",
|
||||
p,
|
||||
searching ? "" :
|
||||
"\nHint: set $SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes environment variable "
|
||||
"to bypass this and further verifications for the directory.");
|
||||
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).%s",
|
||||
p,
|
||||
searching ? "" :
|
||||
"\nHint: set $SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes environment variable "
|
||||
"to bypass this and further verifications for the directory.");
|
||||
|
||||
if (unprivileged_mode)
|
||||
r = verify_xbootldr_udev(devid, flags, ret_uuid);
|
||||
else
|
||||
r = verify_xbootldr_blkid(devid, flags, ret_uuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (unprivileged_mode)
|
||||
r = verify_xbootldr_udev(devid, flags, ret_uuid);
|
||||
else
|
||||
r = verify_xbootldr_blkid(devid, flags, ret_uuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_devid)
|
||||
*ret_devid = devid;
|
||||
|
||||
return 0;
|
||||
|
||||
finish:
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
if (ret_devid)
|
||||
*ret_devid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_xbootldr_and_warn_at_full(
|
||||
@@ -799,6 +782,7 @@ int find_xbootldr_and_warn_at_full(
|
||||
const char *path,
|
||||
int unprivileged_mode,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
@@ -812,7 +796,7 @@ int find_xbootldr_and_warn_at_full(
|
||||
flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_XBOOTLDR_CHECKS");
|
||||
|
||||
if (path)
|
||||
return verify_xbootldr(rfd, path, flags, ret_path, ret_uuid, ret_devid);
|
||||
return verify_xbootldr(rfd, path, flags, ret_path, ret_fd, ret_uuid, ret_devid);
|
||||
|
||||
path = getenv("SYSTEMD_XBOOTLDR_PATH");
|
||||
if (path) {
|
||||
@@ -837,6 +821,8 @@ int find_xbootldr_and_warn_at_full(
|
||||
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(p);
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_uuid)
|
||||
*ret_uuid = SD_ID128_NULL;
|
||||
if (ret_devid)
|
||||
@@ -845,7 +831,14 @@ int find_xbootldr_and_warn_at_full(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = verify_xbootldr(rfd, "/boot", flags | VERIFY_ESP_SEARCHING, ret_path, ret_uuid, ret_devid);
|
||||
r = verify_xbootldr(
|
||||
rfd,
|
||||
"/boot",
|
||||
flags | VERIFY_ESP_SEARCHING,
|
||||
ret_path,
|
||||
ret_fd,
|
||||
ret_uuid,
|
||||
ret_devid);
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -ENOENT, -EADDRNOTAVAIL, -ENOTDIR, -ENOTTY)) /* This one is not it */
|
||||
return r;
|
||||
@@ -861,15 +854,13 @@ int find_xbootldr_and_warn_full(
|
||||
const char *path,
|
||||
int unprivileged_mode,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
sd_id128_t uuid;
|
||||
dev_t devid;
|
||||
int r;
|
||||
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
if (empty_or_root(root))
|
||||
rfd = XAT_FDROOT;
|
||||
else {
|
||||
@@ -878,11 +869,16 @@ int find_xbootldr_and_warn_full(
|
||||
return -errno;
|
||||
}
|
||||
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
sd_id128_t uuid;
|
||||
dev_t devid;
|
||||
r = find_xbootldr_and_warn_at_full(
|
||||
rfd,
|
||||
path,
|
||||
unprivileged_mode,
|
||||
ret_path ? &p : NULL,
|
||||
ret_fd ? &fd : NULL,
|
||||
ret_uuid ? &uuid : NULL,
|
||||
ret_devid ? &devid : NULL);
|
||||
if (r < 0)
|
||||
@@ -893,6 +889,8 @@ int find_xbootldr_and_warn_full(
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_uuid)
|
||||
*ret_uuid = uuid;
|
||||
if (ret_devid)
|
||||
|
||||
+12
-12
@@ -4,22 +4,22 @@
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
int find_esp_and_warn_at_full(int rfd, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_esp_and_warn_full(const char *root, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_esp_and_warn_at_full(int rfd, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_esp_and_warn_full(const char *root, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
|
||||
static inline int find_esp_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path) {
|
||||
return find_esp_and_warn_at_full(rfd, path, unprivileged_mode, ret_path, NULL, NULL, NULL, NULL, NULL);
|
||||
static inline int find_esp_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd) {
|
||||
return find_esp_and_warn_at_full(rfd, path, unprivileged_mode, ret_path, ret_fd, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
static inline int find_esp_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path) {
|
||||
return find_esp_and_warn_full(root, path, unprivileged_mode, ret_path, NULL, NULL, NULL, NULL, NULL);
|
||||
static inline int find_esp_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd) {
|
||||
return find_esp_and_warn_full(root, path, unprivileged_mode, ret_path, ret_fd, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int find_xbootldr_and_warn_at_full(int rfd, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_xbootldr_and_warn_full(const char *root, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_xbootldr_and_warn_at_full(int rfd, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
int find_xbootldr_and_warn_full(const char *root, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd, sd_id128_t *ret_uuid, dev_t *ret_devid);
|
||||
|
||||
static inline int find_xbootldr_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path) {
|
||||
return find_xbootldr_and_warn_at_full(rfd, path, unprivileged_mode, ret_path, NULL, NULL);
|
||||
static inline int find_xbootldr_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd) {
|
||||
return find_xbootldr_and_warn_at_full(rfd, path, unprivileged_mode, ret_path, ret_fd, NULL, NULL);
|
||||
}
|
||||
static inline int find_xbootldr_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path) {
|
||||
return find_xbootldr_and_warn_full(root, path, unprivileged_mode, ret_path, NULL, NULL);
|
||||
static inline int find_xbootldr_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, int *ret_fd) {
|
||||
return find_xbootldr_and_warn_full(root, path, unprivileged_mode, ret_path, ret_fd, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -839,9 +839,9 @@ int resource_resolve_path(
|
||||
} else { /* boot, esp, or xbootldr */
|
||||
r = 0;
|
||||
if (IN_SET(rr->path_relative_to, PATH_RELATIVE_TO_BOOT, PATH_RELATIVE_TO_XBOOTLDR))
|
||||
r = find_xbootldr_and_warn(root, /* path= */ NULL, /* unprivileged_mode= */ -1, &relative_to);
|
||||
r = find_xbootldr_and_warn(root, /* path= */ NULL, /* unprivileged_mode= */ -1, &relative_to, /* ret_fd= */ NULL);
|
||||
if (r == -ENOKEY || rr->path_relative_to == PATH_RELATIVE_TO_ESP)
|
||||
r = find_esp_and_warn(root, /* path= */ NULL, /* unprivileged_mode= */ -1, &relative_to);
|
||||
r = find_esp_and_warn(root, /* path= */ NULL, /* unprivileged_mode= */ -1, &relative_to, /* ret_fd= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve $BOOT: %m");
|
||||
log_debug("Resolved $BOOT to '%s'", relative_to);
|
||||
|
||||
+28
-16
@@ -147,32 +147,44 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find 'swtpm' binary: %m");
|
||||
|
||||
_cleanup_free_ char *_esp = NULL;
|
||||
const char *esp;
|
||||
if (in_initrd())
|
||||
_cleanup_free_ char *state_dir = NULL;
|
||||
_cleanup_close_ int state_fd = -EBADF;
|
||||
if (in_initrd()) {
|
||||
/* The early ESP support uses only a single mount point, we do not need to search for it. */
|
||||
esp = "/sysefi";
|
||||
else {
|
||||
r = chase("/loader/swtpm",
|
||||
"/sysefi",
|
||||
CHASE_PREFIX_ROOT|CHASE_TRIGGER_AUTOFS|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
&state_dir,
|
||||
&state_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open swtpm state directory in ESP: %m");
|
||||
} else {
|
||||
_cleanup_free_ char *esp_path = NULL;
|
||||
_cleanup_close_ int esp_fd = -EBADF;
|
||||
r = find_esp_and_warn(
|
||||
/* root= */ NULL,
|
||||
/* path= */ NULL,
|
||||
/* unprivileged_mode= */ false,
|
||||
&_esp);
|
||||
&esp_path,
|
||||
&esp_fd);
|
||||
if (r == -ENOKEY) /* This one find_esp_and_warn() doesn't actually log about. */
|
||||
return log_error_errno(r, "No ESP discovered.");
|
||||
if (r < 0)
|
||||
return r;
|
||||
esp = _esp;
|
||||
}
|
||||
|
||||
_cleanup_free_ char *state_dir = NULL;
|
||||
_cleanup_close_ int state_fd = -EBADF;
|
||||
r = chase("/loader/swtpm",
|
||||
esp, CHASE_PREFIX_ROOT|CHASE_TRIGGER_AUTOFS|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
&state_dir,
|
||||
&state_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open swtpm state directory in ESP: %m");
|
||||
_cleanup_free_ char *unprefixed_state_dir = NULL;
|
||||
r = chaseat(esp_fd,
|
||||
"/loader/swtpm",
|
||||
CHASE_TRIGGER_AUTOFS|CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY,
|
||||
&unprefixed_state_dir,
|
||||
&state_fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open swtpm state directory in ESP: %m");
|
||||
|
||||
state_dir = path_join(esp_path, unprefixed_state_dir);
|
||||
if (!state_dir)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
_cleanup_(unlink_and_freep) char *secret = NULL;
|
||||
r = prepare_secret(runtime_dir, &secret);
|
||||
|
||||
Reference in New Issue
Block a user