Merge pull request #29345 from poettering/measured-uki-condition

pid1: introduce ConditionSecurity=measured-uki
This commit is contained in:
Lennart Poettering 2023-09-27 16:39:46 +02:00 committed by GitHub
commit 174e8e9897
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 85 additions and 31 deletions

3
TODO
View file

@ -205,9 +205,6 @@ Features:
2nd key derived from volume key of the user, with which to wrap all
keys. maintain keys in kernel keyring if possible.
* add ConditionSecurity=stub-measured or so that checks if we are booted with
systemd-stub and its measurements
* sd-boot should probably measure its configuration file to PCR 5 at boot, as
per TCG PC Client Platform Firmware Profile Spec.

View file

@ -1479,11 +1479,67 @@
<term><varname>ConditionSecurity=</varname></term>
<listitem><para><varname>ConditionSecurity=</varname> may be used to check whether the given
security technology is enabled on the system. Currently, the recognized values are
<literal>selinux</literal>, <literal>apparmor</literal>, <literal>tomoyo</literal>,
<literal>ima</literal>, <literal>smack</literal>, <literal>audit</literal>,
<literal>uefi-secureboot</literal>, <literal>tpm2</literal> and <literal>cvm</literal>.
The test may be negated by prepending an exclamation mark.</para>
security technology is enabled on the system. Currently, the following values are recognized:</para>
<table>
<title>Recognized security technologies</title>
<tgroup cols='2'>
<colspec colname='value'/>
<colspec colname='description'/>
<thead>
<row>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>selinux</entry>
<entry>SELinux MAC</entry>
</row>
<row>
<entry>apparmor</entry>
<entry>AppArmor MAC</entry>
</row>
<row>
<entry>tomoyo</entry>
<entry>Tomoyo MAC</entry>
</row>
<row>
<entry>smack</entry>
<entry>SMACK MAC</entry>
</row>
<row>
<entry>ima</entry>
<entry>Integrity Measurement Architecture (IMA)</entry>
</row>
<row>
<entry>audit</entry>
<entry>Linux Audit Framework</entry>
</row>
<row>
<entry>uefi-secureboot</entry>
<entry>UEFI SecureBoot</entry>
</row>
<row>
<entry>tpm2</entry>
<entry>Trusted Platform Module 2.0 (TPM2)</entry>
</row>
<row>
<entry>cvm</entry>
<entry>Confidential virtual machine (SEV/TDX)</entry>
</row>
<row>
<entry>measured-uki</entry>
<entry>Unified Kernel Image with PCR 11 Measurements, as per <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>. <xi:include href="version-info.xml" xpointer="v255"/></entry>
</row>
</tbody>
</tgroup>
</table>
<para>The test may be negated by prepending an exclamation mark.</para>
<xi:include href="version-info.xml" xpointer="v244"/>
</listitem>

View file

@ -824,7 +824,7 @@ static int measure_volume_key(
return 0;
}
r = efi_stub_measured(LOG_WARNING);
r = efi_measured_uki(LOG_WARNING);
if (r < 0)
return r;
if (r == 0) {

View file

@ -650,7 +650,7 @@ static int add_mount(
}
if (flags & MOUNT_PCRFS) {
r = efi_stub_measured(LOG_WARNING);
r = efi_measured_uki(LOG_WARNING);
if (r == 0)
log_debug("Kernel stub did not measure kernel image into PCR, skipping userspace measurement, too.");
else if (r > 0) {

View file

@ -106,7 +106,7 @@ static int add_cryptsetup(
* assignment, under the assumption that people who are fine to use sd-stub with its PCR
* assignments are also OK with our PCR 15 use here. */
r = efi_stub_measured(LOG_WARNING);
r = efi_measured_uki(LOG_WARNING);
if (r == 0)
log_debug("Will not measure volume key of volume '%s', not booted via systemd-stub with measurements enabled.", id);
else if (r > 0) {

View file

@ -351,7 +351,7 @@ static int run(int argc, char *argv[]) {
length = strlen(word);
/* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */
r = efi_stub_measured(LOG_ERR);
r = efi_measured_uki(LOG_ERR);
if (r < 0)
return r;
if (r == 0) {

View file

@ -28,6 +28,7 @@
#include "cpu-set-util.h"
#include "creds-util.h"
#include "efi-api.h"
#include "efi-loader.h"
#include "env-file.h"
#include "env-util.h"
#include "extract-word.h"
@ -692,6 +693,8 @@ static int condition_test_security(Condition *c, char **env) {
return has_tpm2();
if (streq(c->parameter, "cvm"))
return detect_confidential_virtualization() > 0;
if (streq(c->parameter, "measured-uki"))
return efi_measured_uki(LOG_DEBUG);
return false;
}

View file

@ -238,11 +238,15 @@ int efi_stub_get_features(uint64_t *ret) {
return 0;
}
int efi_stub_measured(int log_level) {
int efi_measured_uki(int log_level) {
_cleanup_free_ char *pcr_string = NULL;
static int cached = -1;
unsigned pcr_nr;
int r;
if (cached >= 0)
return cached;
/* Checks if we are booted on a kernel with sd-stub which measured the kernel into PCR 11. Or in
* other words, if we are running on a TPM enabled UKI.
*
@ -253,16 +257,16 @@ int efi_stub_measured(int log_level) {
r = getenv_bool_secure("SYSTEMD_FORCE_MEASURE"); /* Give user a chance to override the variable test,
* for debugging purposes */
if (r >= 0)
return r;
return (cached = r);
if (r != -ENXIO)
log_debug_errno(r, "Failed to parse $SYSTEMD_FORCE_MEASURE, ignoring: %m");
if (!is_efi_boot())
return 0;
return (cached = 0);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string);
if (r == -ENOENT)
return 0;
return (cached = 0);
if (r < 0)
return log_full_errno(log_level, r,
"Failed to get StubPcrKernelImage EFI variable: %m");
@ -276,7 +280,7 @@ int efi_stub_measured(int log_level) {
"Kernel stub measured kernel image into PCR %u, which is different than expected %i.",
pcr_nr, TPM2_PCR_KERNEL_BOOT);
return 1;
return (cached = 1);
}
int efi_loader_get_config_timeout_one_shot(usec_t *ret) {

View file

@ -18,7 +18,7 @@ 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_stub_measured(int log_level);
int efi_measured_uki(int log_level);
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);
@ -45,7 +45,7 @@ static inline int efi_stub_get_features(uint64_t *ret) {
return -EOPNOTSUPP;
}
static inline int efi_stub_measured(int log_level) {
static inline int efi_measured_uki(int log_level) {
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"Compiled without support for EFI");
}

View file

@ -15,8 +15,7 @@ Conflicts=shutdown.target
After=systemd-pcrmachine.service
Before=shutdown.target
ConditionPathExists=!/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot

View file

@ -16,8 +16,7 @@ Conflicts=shutdown.target
After=%i.mount systemd-pcrfs-root.service
Before=shutdown.target
ConditionPathExists=!/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot

View file

@ -14,8 +14,7 @@ DefaultDependencies=no
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
ConditionPathExists=!/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot

View file

@ -14,8 +14,7 @@ DefaultDependencies=no
Conflicts=shutdown.target initrd-switch-root.target
Before=sysinit.target cryptsetup-pre.target cryptsetup.target shutdown.target initrd-switch-root.target systemd-sysext.service
ConditionPathExists=/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot

View file

@ -15,8 +15,7 @@ Conflicts=shutdown.target
After=sysinit.target
Before=basic.target shutdown.target
ConditionPathExists=!/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot

View file

@ -13,8 +13,7 @@ Documentation=man:systemd-pcrphase.service(8)
After=remote-fs.target remote-cryptsetup.target
Before=systemd-user-sessions.service
ConditionPathExists=!/etc/initrd-release
ConditionSecurity=tpm2
ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionSecurity=measured-uki
[Service]
Type=oneshot