]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: when updating everything check PE machine type 37913/head
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Jun 2025 12:03:57 +0000 (14:03 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Jun 2025 12:06:53 +0000 (14:06 +0200)
Let's never accidentally over-write foreign-arch PE binaries with native
ones.

Fixes: #33413
src/bootctl/bootctl-install.c
src/shared/pe-binary.c
src/shared/pe-binary.h

index 426a821168cdc23677ae2765fb5f5ea1e8fea361..f751914b58da279ce1671e3c2e66ecdf1444bb72 100644 (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"
@@ -356,20 +357,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;
@@ -1109,14 +1117,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 627c59cac8de0ae0d022ea91da3e755be6664409..1dfda07142cf145fa33295ace3a165050ebb8495 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 2daaf7eea9f787f1a353bb6c3b24651da50e95c3..2579dd9ae8ba3575b80829aba1ed416ac1653530 100644 (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);