bootctl: honour architecture when updating boot loaders (#37913)

Fixes: #33413
Follow-up for: #30418
This commit is contained in:
Yu Watanabe
2025-06-21 02:25:17 +09:00
committed by GitHub
3 changed files with 40 additions and 13 deletions
+28 -13
View File
@@ -28,6 +28,7 @@
#include "openssl-util.h"
#include "parse-argument.h"
#include "path-util.h"
#include "pe-binary.h"
#include "rm-rf.h"
#include "stat-util.h"
#include "string-util.h"
@@ -352,24 +353,31 @@ static int update_efi_boot_binaries(const char *esp_path, const char *source_pat
if (!endswith_no_case(de->d_name, ".efi"))
continue;
fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC);
fd = xopenat_full(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW, XO_REGULAR, /* mode= */ 0);
if (fd < 0)
return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name);
return log_error_errno(fd, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name);
r = pe_is_native_fd(fd);
if (r < 0) {
log_warning_errno(r, "Failed to detect if \"%s/%s\" is native architecture, ignoring: %m", p, de->d_name);
continue;
}
if (r == 0)
continue;
r = get_file_version(fd, &v);
if (r == -ESRCH)
continue; /* No version information */
if (r < 0)
return r;
if (startswith(v, "systemd-boot ")) {
_cleanup_free_ char *dest_path = NULL;
if (!startswith(v, "systemd-boot "))
continue;
dest_path = path_join(p, de->d_name);
if (!dest_path)
return log_oom();
_cleanup_free_ char *dest_path = path_join(p, de->d_name);
if (!dest_path)
return log_oom();
RET_GATHER(ret, copy_file_with_version_check(source_path, dest_path, /* force = */ false));
}
RET_GATHER(ret, copy_file_with_version_check(source_path, dest_path, /* force = */ false));
}
return ret;
@@ -1105,9 +1113,17 @@ static int remove_boot_efi(const char *esp_path) {
if (!endswith_no_case(de->d_name, ".efi"))
continue;
fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC);
fd = xopenat_full(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW, XO_REGULAR, /* mode= */ 0);
if (fd < 0)
return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name);
return log_error_errno(fd, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name);
r = pe_is_native_fd(fd);
if (r < 0) {
log_warning_errno(r, "Failed to detect if \"%s/%s\" is native architecture, ignoring: %m", p, de->d_name);
continue;
}
if (r == 0)
continue;
r = get_file_version(fd, &v);
if (r == -ESRCH)
@@ -1115,8 +1131,7 @@ static int remove_boot_efi(const char *esp_path) {
if (r < 0)
return r;
if (startswith(v, "systemd-boot ")) {
r = unlinkat(dirfd(d), de->d_name, 0);
if (r < 0)
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
return log_error_errno(errno, "Failed to remove \"%s/%s\": %m", p, de->d_name);
log_info("Removed \"%s/%s\".", p, de->d_name);
+11
View File
@@ -290,6 +290,17 @@ bool pe_is_native(const PeHeader *pe_header) {
#endif
}
int pe_is_native_fd(int fd) {
_cleanup_free_ PeHeader *pe_header = NULL;
int r;
r = pe_load_headers(fd, /* ret_dos_header= */ NULL, &pe_header);
if (r < 0)
return r;
return pe_is_native(pe_header);
}
/* Implements:
*
* https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx
+1
View File
@@ -149,6 +149,7 @@ bool pe_is_uki(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections);
bool pe_is_addon(const PeHeader *pe_header, const IMAGE_SECTION_HEADER *sections);
bool pe_is_native(const PeHeader *pe_header);
int pe_is_native_fd(int fd);
int pe_hash(int fd, const EVP_MD *md, void **ret_hash, size_t *ret_hash_size);