]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootspec: refactor find_sections
authorEmanuele Giuseppe Esposito <eesposit@redhat.com>
Thu, 21 Sep 2023 06:18:32 +0000 (02:18 -0400)
committerEmanuele Giuseppe Esposito <eesposit@redhat.com>
Wed, 14 Feb 2024 09:56:42 +0000 (04:56 -0500)
Prepare for the incoming changes that introduce PE addons support.
Addons will contain a .cmdline section, but not .osrel.

src/shared/bootspec.c

index f4b2fdc5d142b02889269b4ad1b1c94c6a317df3..3e1e9c32b4938d8e73c191f15e35d8b15a2a4e3b 100644 (file)
@@ -753,13 +753,12 @@ static int boot_entry_load_unified(
 static int find_sections(
                 int fd,
                 const char *path,
-                char **ret_osrelease,
-                char **ret_cmdline) {
+                IMAGE_SECTION_HEADER **ret_sections,
+                PeHeader **ret_pe_header) {
 
-        _cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
         _cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
-        _cleanup_free_ char *osrel = NULL, *cmdline = NULL;
-        _cleanup_free_ PeHeader *pe_header = NULL;
+        IMAGE_SECTION_HEADER *sections;
+        PeHeader *pe_header;
         int r;
 
         assert(fd >= 0);
@@ -773,25 +772,85 @@ static int find_sections(
         if (r < 0)
                 return log_warning_errno(r, "Failed to parse PE sections of '%s': %m", path);
 
-        if (!pe_is_uki(pe_header, sections))
-                return log_warning_errno(SYNTHETIC_ERRNO(EBADMSG), "Parsed PE file '%s' is not a UKI.", path);
+        if (ret_pe_header)
+                *ret_pe_header = TAKE_PTR(pe_header);
+        if (ret_sections)
+                *ret_sections = TAKE_PTR(sections);
 
-        r = pe_read_section_data(fd, pe_header, sections, ".osrel", PE_SECTION_SIZE_MAX, (void**) &osrel, NULL);
-        if (r < 0)
-                return log_warning_errno(r, "Failed to read .osrel section of '%s': %m", path);
+        return 0;
+}
+
+static int find_cmdline_section(
+                int fd,
+                const char *path,
+                IMAGE_SECTION_HEADER *sections,
+                PeHeader *pe_header,
+                char **ret_cmdline) {
+
+        int r;
+        char *cmdline = NULL;
+
+        if (!ret_cmdline)
+                return 0;
 
         r = pe_read_section_data(fd, pe_header, sections, ".cmdline", PE_SECTION_SIZE_MAX, (void**) &cmdline, NULL);
-        if (r < 0 && r != -ENXIO) /* cmdline is optional */
+        if (r == -ENXIO) /* cmdline is optional */
+                *ret_cmdline = NULL;
+        else if (r < 0)
                 return log_warning_errno(r, "Failed to read .cmdline section of '%s': %m", path);
-
-        if (ret_osrelease)
-                *ret_osrelease = TAKE_PTR(osrel);
-        if (ret_cmdline)
+        else if (ret_cmdline)
                 *ret_cmdline = TAKE_PTR(cmdline);
 
         return 0;
 }
 
+static int find_osrel_section(
+                int fd,
+                const char *path,
+                IMAGE_SECTION_HEADER *sections,
+                PeHeader *pe_header,
+                char **ret_osrelease) {
+
+        int r;
+
+        if (!ret_osrelease)
+                return 0;
+
+        r = pe_read_section_data(fd, pe_header, sections, ".osrel", PE_SECTION_SIZE_MAX, (void**) ret_osrelease, NULL);
+        if (r < 0)
+                return log_warning_errno(r, "Failed to read .osrel section of '%s': %m", path);
+
+        return 0;
+}
+
+static int find_uki_sections(
+                int fd,
+                const char *path,
+                char **ret_osrelease,
+                char **ret_cmdline) {
+
+        _cleanup_free_ IMAGE_SECTION_HEADER *sections = NULL;
+        _cleanup_free_ PeHeader *pe_header = NULL;
+        int r;
+
+        r = find_sections(fd, path, &sections, &pe_header);
+        if (r < 0)
+                return r;
+
+        if (!pe_is_uki(pe_header, sections))
+                return log_warning_errno(SYNTHETIC_ERRNO(EBADMSG), "Parsed PE file '%s' is not a UKI.", path);
+
+        r = find_osrel_section(fd, path, sections, pe_header, ret_osrelease);
+        if (r < 0)
+                return r;
+
+        r = find_cmdline_section(fd, path, sections, pe_header, ret_cmdline);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 static int boot_entries_find_unified(
                 BootConfig *config,
                 const char *root,
@@ -839,7 +898,7 @@ static int boot_entries_find_unified(
                 if (!j)
                         return log_oom();
 
-                if (find_sections(fd, j, &osrelease, &cmdline) < 0)
+                if (find_uki_sections(fd, j, &osrelease, &cmdline) < 0)
                         continue;
 
                 r = boot_entry_load_unified(root, j, osrelease, cmdline, config->entries + config->n_entries);