]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: calculate secureboot state taking MokSBStateRT into account (#39298)
authorDimitri John Ledkov <19779+xnox@users.noreply.github.com>
Tue, 11 Nov 2025 23:47:44 +0000 (23:47 +0000)
committerGitHub <noreply@github.com>
Tue, 11 Nov 2025 23:47:44 +0000 (08:47 +0900)
shim is often used as part of the EFI boot chain with Linux kernels.

shim has an option to disable all verification of binaries it loads.
This can be performed by end-user using mokutil / mokmanager EFI app,
which set BootServices only variable MokSBState. shim honors that, and
mirrors it as readonly MokSBStateRT for the post-ExitBootService access.

Thus presense of MokSBStateRT is an indicator that shim was used during
boot chain.

Some OEM vendors are known to set MokSBState variable, without user
having done so.

When verification is disabled, one should assume secureboot is insecure,
because any EFI binary was allowed to run, including but not limited to
unsigned or revoked:
- grub
- systemd-boot
- UKI
- linux kernel

Linux kernel also has code to check this variable, and correctly report
that Secure Boot is disabled, see:
-
https://github.com/torvalds/linux/blob/3a8660878839faadb4f1a6dd72c3179c1df56787/drivers/firmware/efi/libstub/secureboot.c#L57

With this change bootctl output changes like this:
```diff
 System:
       Firmware: n/a (n/a)
  Firmware Arch: x64
-   Secure Boot: enabled (user)
+   Secure Boot: disabled (insecure)
   TPM2 Support: yes
   Measured UKI: no
   Boot into FW: supported
```

This implementation is trying to mimic mokutil behaviour like this one:
```
$ mokutil --sb-state
SecureBoot enabled
SecureBoot validation is disabled in shim
```

As well as the linux kernel behavior of:
```
$ journalctl -b | grep 'Secure boot disabled'
kernel: Secure boot disabled
```

Note that MokSBState is extended into PCR7 as well as also into PCR14.
For more details see https://github.com/rhboot/shim/blob/main/README.tpm

src/basic/efivars.c
src/basic/efivars.h
src/boot/secure-boot.c
src/boot/shim.c
src/fundamental/efi-fundamental.h
src/fundamental/efivars-fundamental.c
src/fundamental/efivars-fundamental.h

index 99c47e8ce2e9bde1a5a8db99ffa9139b6acedf4b..b5e12eda62ce288ad34360f5d1b73416f618dc2f 100644 (file)
@@ -377,10 +377,11 @@ SecureBootMode efi_get_secure_boot_mode(void) {
         int audit    = read_flag(EFI_GLOBAL_VARIABLE_STR("AuditMode"));
         int deployed = read_flag(EFI_GLOBAL_VARIABLE_STR("DeployedMode"));
         int setup    = read_flag(EFI_GLOBAL_VARIABLE_STR("SetupMode"));
-        log_debug("Secure boot variables: SecureBoot=%d AuditMode=%d DeployedMode=%d SetupMode=%d",
-                  secure, audit, deployed, setup);
+        int moksb    = read_flag(EFI_SHIMLOCK_VARIABLE_STR("MokSBStateRT"));
+        log_debug("Secure boot variables: SecureBoot=%d AuditMode=%d DeployedMode=%d SetupMode=%d MokSBStateRT=%d",
+                  secure, audit, deployed, setup, moksb);
 
-        return (cache = decode_secure_boot_mode(secure, audit > 0, deployed > 0, setup > 0));
+        return (cache = decode_secure_boot_mode(secure, audit > 0, deployed > 0, setup > 0, moksb > 0));
 }
 #endif
 
index e4cbf53f55f722d183736acf3d1e79b3cb16d0fb..93c918847af55eaa6b3ac34872f1ff4df2e2a59f 100644 (file)
@@ -15,6 +15,8 @@
 #define EFI_VENDOR_DATABASE_STR SD_ID128_MAKE_UUID_STR(d7,19,b2,cb,3d,3a,45,96,a3,bc,da,d0,0e,67,65,6f)
 #define EFI_VENDOR_SYSTEMD      SD_ID128_MAKE(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
 #define EFI_VENDOR_SYSTEMD_STR  SD_ID128_MAKE_UUID_STR(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
+#define EFI_VENDOR_SHIMLOCK     SD_ID128_MAKE(60,5d,ab,50,e0,46,43,00,ab,b6,3d,d8,10,dd,8b,23)
+#define EFI_VENDOR_SHIMLOCK_STR SD_ID128_MAKE_UUID_STR(60,5d,ab,50,e0,46,43,00,ab,b6,3d,d8,10,dd,8b,23)
 
 #define EFI_VARIABLE_NON_VOLATILE                          UINT32_C(0x00000001)
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS                    UINT32_C(0x00000002)
@@ -30,6 +32,7 @@
 #define EFI_GLOBAL_VARIABLE_STR(name) EFI_VENDOR_VARIABLE_STR(EFI_VENDOR_GLOBAL_STR, name)
 #define EFI_LOADER_VARIABLE_STR(name) EFI_VENDOR_VARIABLE_STR(EFI_VENDOR_LOADER_STR, name)
 #define EFI_SYSTEMD_VARIABLE_STR(name) EFI_VENDOR_VARIABLE_STR(EFI_VENDOR_SYSTEMD_STR, name)
+#define EFI_SHIMLOCK_VARIABLE_STR(name) EFI_VENDOR_VARIABLE_STR(EFI_VENDOR_SHIMLOCK_STR, name)
 
 #define EFIVAR_PATH(variable) "/sys/firmware/efi/efivars/" variable
 #define EFIVAR_CACHE_PATH(variable) "/run/systemd/efivars/" variable
index 1c5f84050726a957e8937364712840f2fb220036..7f599b0bcc215ef4f18cacbfe20d4cc13ae142d8 100644 (file)
@@ -20,7 +20,7 @@ bool secure_boot_enabled(void) {
 }
 
 SecureBootMode secure_boot_mode(void) {
-        bool secure, audit = false, deployed = false, setup = false;
+        bool secure, audit = false, deployed = false, setup = false, moksb = false;
         EFI_STATUS err;
 
         err = efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"SecureBoot", &secure);
@@ -32,8 +32,9 @@ SecureBootMode secure_boot_mode(void) {
         (void) efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"AuditMode", &audit);
         (void) efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"DeployedMode", &deployed);
         (void) efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"SetupMode", &setup);
+        (void) efivar_get_boolean_u8(MAKE_GUID_PTR(SHIM_LOCK), u"MokSBStateRT", &moksb);
 
-        return decode_secure_boot_mode(secure, audit, deployed, setup);
+        return decode_secure_boot_mode(secure, audit, deployed, setup, moksb);
 }
 
 /*
index 0168bb424d84d86f8f8ac180c6b5b4e8b410950a..e50cac233a46d760888dac3f287ec97878a2e4cd 100644 (file)
@@ -30,9 +30,6 @@ struct ShimLock {
         EFI_STATUS __sysv_abi__ (*read_header) (void *data, uint32_t datasize, void *context);
 };
 
-#define SHIM_LOCK_GUID \
-        { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
-
 #define SHIM_IMAGE_LOADER_GUID \
         { 0x1f492041, 0xfadb, 0x4e59, { 0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } }
 
index f72290e1b3f050ab677d24a5612c55add228f8eb..967e92f5995b809822a120cda9160fe7b5429694 100644 (file)
@@ -80,3 +80,6 @@ typedef struct {
         GUID_DEF(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
 #define EFI_CERT_TYPE_PKCS7_GUID \
         GUID_DEF(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
+
+#define SHIM_LOCK_GUID \
+        GUID_DEF(0x605dab50, 0xe046, 0x4300 ,0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
index 2ec3bfb2f0ee7309ae38999f0a46f656dcda9051..611b0b682d9b77f89c17ce4466896fc110176634 100644 (file)
@@ -10,13 +10,17 @@ static const sd_char * const table[_SECURE_BOOT_MAX] = {
         [SECURE_BOOT_DEPLOYED]    = STR_C("deployed"),
         [SECURE_BOOT_SETUP]       = STR_C("setup"),
         [SECURE_BOOT_USER]        = STR_C("user"),
+        [SECURE_BOOT_TAINTED]     = STR_C("tainted"),
 };
 
 const sd_char *secure_boot_mode_to_string(SecureBootMode m) {
         return (m >= 0 && m < _SECURE_BOOT_MAX) ? table[m] : NULL;
 }
 
-SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup) {
+SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup, bool moksb) {
+        /* shim verification can be disabled by moksb, some OEMs set it */
+        if (secure && moksb)
+                return SECURE_BOOT_TAINTED;
         /* See figure 32-4 Secure Boot Modes from UEFI Specification 2.9 */
         if (secure && deployed && !audit && !setup)
                 return SECURE_BOOT_DEPLOYED;
index 0f4670a37fd01c3efc7d3ea6628ec49bcd482d76..df94a736e1ca6494c16c61729f333d45c75019b0 100644 (file)
@@ -51,9 +51,10 @@ typedef enum SecureBootMode {
         SECURE_BOOT_DEPLOYED,
         SECURE_BOOT_SETUP,
         SECURE_BOOT_USER,
+        SECURE_BOOT_TAINTED,
         _SECURE_BOOT_MAX,
         _SECURE_BOOT_INVALID = -EINVAL,
 } SecureBootMode;
 
 const sd_char *secure_boot_mode_to_string(SecureBootMode m);
-SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup);
+SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup, bool moksb);