]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: show stub feature set in status output
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Jul 2022 13:28:55 +0000 (15:28 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Aug 2022 08:28:49 +0000 (10:28 +0200)
src/boot/bootctl.c
src/shared/efi-loader.c
src/shared/efi-loader.h

index 7470157ecd5652d7e8647c2e6e52270ea7fe816c..e53328ca39e8435281241522bfdf6373418efebc 100644 (file)
@@ -1714,7 +1714,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 static const struct {
                         uint64_t flag;
                         const char *name;
-                } flags[] = {
+                } loader_flags[] = {
                         { EFI_LOADER_FEATURE_BOOT_COUNTING,           "Boot counting"                         },
                         { EFI_LOADER_FEATURE_CONFIG_TIMEOUT,          "Menu timeout control"                  },
                         { EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT, "One-shot menu timeout control"         },
@@ -1724,9 +1724,18 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                         { EFI_LOADER_FEATURE_RANDOM_SEED,             "Support for passing random seed to OS" },
                         { EFI_LOADER_FEATURE_LOAD_DRIVER,             "Load drop-in drivers"                  },
                 };
+                static const struct {
+                        uint64_t flag;
+                        const char *name;
+                } stub_flags[] = {
+                        { EFI_STUB_FEATURE_REPORT_BOOT_PARTITION,     "Stub sets ESP information"                            },
+                        { EFI_STUB_FEATURE_PICK_UP_CREDENTIALS,       "Picks up credentials from boot partition"             },
+                        { EFI_STUB_FEATURE_PICK_UP_SYSEXTS,           "Picks up system extension images from boot partition" },
+                        { EFI_STUB_FEATURE_THREE_PCRS,                "Measures kernel+command line+sysexts"                 },
+                };
                 _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL;
                 sd_id128_t loader_part_uuid = SD_ID128_NULL;
-                uint64_t loader_features = 0;
+                uint64_t loader_features = 0, stub_features = 0;
                 Tpm2Support s;
                 int have;
 
@@ -1736,6 +1745,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 read_efi_var(EFI_LOADER_VARIABLE(StubInfo), &stub);
                 read_efi_var(EFI_LOADER_VARIABLE(LoaderImageIdentifier), &loader_path);
                 (void) efi_loader_get_features(&loader_features);
+                (void) efi_stub_get_features(&stub_features);
 
                 if (loader_path)
                         efi_tilt_backslashes(loader_path);
@@ -1777,8 +1787,8 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 printf("Current Boot Loader:\n");
                 printf("      Product: %s%s%s\n", ansi_highlight(), strna(loader), ansi_normal());
 
-                for (size_t i = 0; i < ELEMENTSOF(flags); i++)
-                        print_yes_no_line(i == 0, FLAGS_SET(loader_features, flags[i].flag), flags[i].name);
+                for (size_t i = 0; i < ELEMENTSOF(loader_flags); i++)
+                        print_yes_no_line(i == 0, FLAGS_SET(loader_features, loader_flags[i].flag), loader_flags[i].name);
 
                 sd_id128_t bootloader_esp_uuid;
                 bool have_bootloader_esp_uuid = efi_loader_get_device_part_uuid(&bootloader_esp_uuid) >= 0;
@@ -1787,8 +1797,11 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 if (have_bootloader_esp_uuid && !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
                         printf("WARNING: The boot loader reports a different ESP UUID than detected!\n");
 
-                if (stub)
+                if (stub) {
                         printf("         Stub: %s\n", stub);
+                        for (size_t i = 0; i < ELEMENTSOF(stub_flags); i++)
+                                print_yes_no_line(i == 0, FLAGS_SET(stub_features, stub_flags[i].flag), stub_flags[i].name);
+                }
                 if (!sd_id128_is_null(loader_part_uuid))
                         printf("          ESP: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
                                SD_ID128_FORMAT_VAL(loader_part_uuid));
index e114d5ea2c60af0d3a4c686f59bfb31ad200c272..3eed44a533bb7ea4ec4da1a2624e57b53d7806f6 100644 (file)
@@ -187,6 +187,54 @@ int efi_loader_get_features(uint64_t *ret) {
         return 0;
 }
 
+int efi_stub_get_features(uint64_t *ret) {
+        _cleanup_free_ void *v = NULL;
+        size_t s;
+        int r;
+
+        assert(ret);
+
+        if (!is_efi_boot()) {
+                *ret = 0;
+                return 0;
+        }
+
+        r = efi_get_variable(EFI_LOADER_VARIABLE(StubFeatures), NULL, &v, &s);
+        if (r == -ENOENT) {
+                _cleanup_free_ char *info = NULL;
+
+                /* The new (v252+) StubFeatures variable is not supported, let's see if it's systemd-stub at all */
+                r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubInfo), &info);
+                if (r < 0) {
+                        if (r != -ENOENT)
+                                return r;
+
+                        /* Variable not set, definitely means not systemd-stub */
+
+                } else if (first_word(info, "systemd-stub")) {
+
+                        /* An older systemd-stub version. Let's hardcode the feature set, since it was pretty
+                         * static in all its versions. */
+
+                        *ret = EFI_STUB_FEATURE_REPORT_BOOT_PARTITION;
+                        return 0;
+                }
+
+                /* No features supported */
+                *ret = 0;
+                return 0;
+        }
+        if (r < 0)
+                return r;
+
+        if (s != sizeof(uint64_t))
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "StubFeatures EFI variable doesn't have the right size.");
+
+        memcpy(ret, v, sizeof(uint64_t));
+        return 0;
+}
+
 int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
         _cleanup_free_ char *v = NULL;
         static struct stat cache_stat = {};
index 507160e50de60f7261f9e3f1f00c81f7ee7d1e12..84968869abe2732a8cd64f5b2a4ed89774ea7542 100644 (file)
@@ -16,6 +16,7 @@ int efi_loader_get_boot_usec(usec_t *ret_firmware, usec_t *ret_loader);
 int efi_loader_get_entries(char ***ret);
 
 int efi_loader_get_features(uint64_t *ret);
+int efi_stub_get_features(uint64_t *ret);
 
 int efi_loader_get_config_timeout_one_shot(usec_t *ret);
 int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat);
@@ -38,6 +39,10 @@ static inline int efi_loader_get_features(uint64_t *ret) {
         return -EOPNOTSUPP;
 }
 
+static inline int efi_stub_get_features(uint64_t *ret) {
+        return -EOPNOTSUPP;
+}
+
 static inline int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
         return -EOPNOTSUPP;
 }