diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-04-12 22:59:54 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-12 22:59:54 +0900 |
commit | 8e1d6003fb4c919b35955bca853bc4f151bb9e3f (patch) | |
tree | ced3b042654db53dceab92530ba8252343bb8986 | |
parent | 14cb10b737fc88d5acb82c626daa219703d00e64 (diff) | |
parent | d2d969bb45ec29bf3594acd64344b4e8671a3b05 (diff) | |
download | systemd-8e1d6003fb4c919b35955bca853bc4f151bb9e3f.tar.gz |
Merge pull request #27217 from yuwata/boot-entry-at
boot-entry: introduce _at() variant
-rw-r--r-- | src/boot/bootctl-util.c | 1 | ||||
-rw-r--r-- | src/shared/boot-entry.c | 88 | ||||
-rw-r--r-- | src/shared/boot-entry.h | 8 |
3 files changed, 72 insertions, 25 deletions
diff --git a/src/boot/bootctl-util.c b/src/boot/bootctl-util.c index d93cc20318..7259f177a8 100644 --- a/src/boot/bootctl-util.c +++ b/src/boot/bootctl-util.c @@ -120,6 +120,7 @@ int settle_entry_token(void) { arg_root, etc_kernel(), arg_machine_id, + /* machine_id_is_random = */ false, &arg_entry_token_type, &arg_entry_token); if (r < 0) diff --git a/src/shared/boot-entry.c b/src/shared/boot-entry.c index 90e72bd754..0595ac6238 100644 --- a/src/shared/boot-entry.c +++ b/src/shared/boot-entry.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "boot-entry.h" +#include "chase.h" +#include "fd-util.h" #include "fileio.h" #include "id128-util.h" #include "os-util.h" @@ -12,10 +14,12 @@ bool boot_entry_token_valid(const char *p) { return utf8_is_valid(p) && string_is_safe(p) && filename_is_valid(p); } -static int entry_token_load(const char *root, const char *etc_kernel, BootEntryTokenType *type, char **token) { +static int entry_token_load(int rfd, const char *etc_kernel, BootEntryTokenType *type, char **token) { _cleanup_free_ char *buf = NULL, *p = NULL; + _cleanup_fclose_ FILE *f = NULL; int r; + assert(rfd >= 0 || rfd == AT_FDCWD); assert(type); assert(*type == BOOT_ENTRY_TOKEN_AUTO); assert(token); @@ -23,14 +27,18 @@ static int entry_token_load(const char *root, const char *etc_kernel, BootEntryT if (!etc_kernel) return 0; - p = path_join(root, etc_kernel, "entry-token"); + p = path_join(etc_kernel, "entry-token"); if (!p) return log_oom(); - r = read_one_line_file(p, &buf); + r = chase_and_fopenat_unlocked(rfd, p, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f); if (r == -ENOENT) return 0; if (r < 0) + return log_error_errno(r, "Failed to chase and open '%s': %m", p); + + r = read_line(f, NAME_MAX, &buf); + if (r < 0) return log_error_errno(r, "Failed to read %s: %m", p); if (isempty(buf)) @@ -65,27 +73,28 @@ static int entry_token_from_machine_id(sd_id128_t machine_id, BootEntryTokenType return 1; } -static int entry_token_from_os_release(const char *root, BootEntryTokenType *type, char **token) { +static int entry_token_from_os_release(int rfd, BootEntryTokenType *type, char **token) { _cleanup_free_ char *id = NULL, *image_id = NULL; int r; + assert(rfd >= 0 || rfd == AT_FDCWD); assert(type); assert(IN_SET(*type, BOOT_ENTRY_TOKEN_AUTO, BOOT_ENTRY_TOKEN_OS_IMAGE_ID, BOOT_ENTRY_TOKEN_OS_ID)); assert(token); switch (*type) { case BOOT_ENTRY_TOKEN_AUTO: - r = parse_os_release(root, - "IMAGE_ID", &image_id, - "ID", &id); + r = parse_os_release_at(rfd, + "IMAGE_ID", &image_id, + "ID", &id); break; case BOOT_ENTRY_TOKEN_OS_IMAGE_ID: - r = parse_os_release(root, "IMAGE_ID", &image_id); + r = parse_os_release_at(rfd, "IMAGE_ID", &image_id); break; case BOOT_ENTRY_TOKEN_OS_ID: - r = parse_os_release(root, "ID", &id); + r = parse_os_release_at(rfd, "ID", &id); break; default: @@ -94,7 +103,7 @@ static int entry_token_from_os_release(const char *root, BootEntryTokenType *typ if (r == -ENOENT) return 0; if (r < 0) - return log_error_errno(r, "Failed to load %s/etc/os-release: %m", strempty(root)); + return log_error_errno(r, "Failed to load /etc/os-release: %m"); if (!isempty(image_id) && boot_entry_token_valid(image_id)) { *token = TAKE_PTR(image_id); @@ -111,15 +120,17 @@ static int entry_token_from_os_release(const char *root, BootEntryTokenType *typ return 0; } -int boot_entry_token_ensure( - const char *root, +int boot_entry_token_ensure_at( + int rfd, const char *etc_kernel, sd_id128_t machine_id, + bool machine_id_is_random, BootEntryTokenType *type, char **token) { int r; + assert(rfd >= 0 || rfd == AT_FDCWD); assert(type); assert(token); @@ -129,21 +140,28 @@ int boot_entry_token_ensure( switch (*type) { case BOOT_ENTRY_TOKEN_AUTO: - r = entry_token_load(root, etc_kernel, type, token); + r = entry_token_load(rfd, etc_kernel, type, token); if (r != 0) return r; - r = entry_token_from_machine_id(machine_id, type, token); - if (r != 0) - return r; + if (!machine_id_is_random) { + r = entry_token_from_machine_id(machine_id, type, token); + if (r != 0) + return r; + } - r = entry_token_from_os_release(root, type, token); + r = entry_token_from_os_release(rfd, type, token); if (r != 0) return r; + if (machine_id_is_random) { + r = entry_token_from_machine_id(machine_id, type, token); + if (r != 0) + return r; + } + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "No machine ID set, and %s/etc/os-release carries no ID=/IMAGE_ID= fields.", - strempty(root)); + "No machine ID set, and /etc/os-release carries no ID=/IMAGE_ID= fields."); case BOOT_ENTRY_TOKEN_MACHINE_ID: r = entry_token_from_machine_id(machine_id, type, token); @@ -153,22 +171,20 @@ int boot_entry_token_ensure( return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No machine ID set."); case BOOT_ENTRY_TOKEN_OS_IMAGE_ID: - r = entry_token_from_os_release(root, type, token); + r = entry_token_from_os_release(rfd, type, token); if (r != 0) return r; return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "IMAGE_ID= field not set in %s/etc/os-release.", - strempty(root)); + "IMAGE_ID= field not set in /etc/os-release."); case BOOT_ENTRY_TOKEN_OS_ID: - r = entry_token_from_os_release(root, type, token); + r = entry_token_from_os_release(rfd, type, token); if (r != 0) return r; return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "ID= field not set in %s/etc/os-release.", - strempty(root)); + "ID= field not set in /etc/os-release."); case BOOT_ENTRY_TOKEN_LITERAL: /* In this case, the token should be already set by the user input. */ @@ -179,6 +195,28 @@ int boot_entry_token_ensure( } } +int boot_entry_token_ensure( + const char *root, + const char *etc_kernel, + sd_id128_t machine_id, + bool machine_id_is_random, + BootEntryTokenType *type, + char **token) { + + assert(token); + + if (*token) + return 0; /* Already set. */ + + _cleanup_close_ int rfd = -EBADF; + + rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH); + if (rfd < 0) + return -errno; + + return boot_entry_token_ensure_at(rfd, etc_kernel, machine_id, machine_id_is_random, type, token); +} + int parse_boot_entry_token_type(const char *s, BootEntryTokenType *type, char **token) { assert(s); assert(type); diff --git a/src/shared/boot-entry.h b/src/shared/boot-entry.h index 97b30702bc..1d20db602a 100644 --- a/src/shared/boot-entry.h +++ b/src/shared/boot-entry.h @@ -19,7 +19,15 @@ int boot_entry_token_ensure( const char *root, const char *etc_kernel, /* will be prefixed with root, typically /etc/kernel. */ sd_id128_t machine_id, + bool machine_id_is_random, BootEntryTokenType *type, /* input and output */ char **token); /* output, but do not pass uninitialized value. */ +int boot_entry_token_ensure_at( + int rfd, + const char *etc_kernel, + sd_id128_t machine_id, + bool machine_id_is_random, + BootEntryTokenType *type, + char **token); int parse_boot_entry_token_type(const char *s, BootEntryTokenType *type, char **token); |