]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: when updating everything check PE machine type
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Jun 2025 12:03:57 +0000 (14:03 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 25 Jun 2025 12:36:10 +0000 (13:36 +0100)
Let's never accidentally over-write foreign-arch PE binaries with native
ones.

Fixes: #33413
(cherry picked from commit 6b8770b96b403407b371e704b4afdcd0851deb3b)

src/bootctl/bootctl-install.c
src/shared/pe-binary.c
src/shared/pe-binary.h

index 9ef3ae4ba645d0d36294bb4072bf1813014f93b9..e15c2c6bedb23ae869c08669c8ab2457f8100689 100644 (file)
@@ -20,6 +20,7 @@
 #include "os-util.h"
 #include "parse-argument.h"
 #include "path-util.h"
+#include "pe-binary.h"
 #include "rm-rf.h"
 #include "stat-util.h"
 #include "sync-util.h"
@@ -345,20 +346,27 @@ static int update_efi_boot_binaries(const char *esp_path, const char *source_pat
                 if (fd < 0)
                         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;
@@ -1106,14 +1114,21 @@ static int remove_boot_efi(const char *esp_path) {
                 if (fd < 0)
                         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 ")) {
-                        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);
index 6bfc4868aecd5808216ac3e28796daf2adf6a7ef..c9bb09c77a40ac988ec71dcdfda373f21a98f5e1 100644 (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
index a93493eb47c72115293455c35f3145273e9f8d47..d36e1055da6a984d4be23f1c160451ff8f1aa7e7 100644 (file)
@@ -152,6 +152,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);