|
|
ac3a84 |
From 1b7dfe48d6d66cad5d0368b8e8b387a4d9586ccd Mon Sep 17 00:00:00 2001
|
|
|
ac3a84 |
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
|
|
ac3a84 |
Date: Thu, 27 Oct 2022 11:12:10 +0200
|
|
|
ac3a84 |
Subject: [PATCH] condition: Check that subsystem is enabled in
|
|
|
ac3a84 |
ConditionSecurity=tpm2
|
|
|
ac3a84 |
|
|
|
ac3a84 |
Instead of succeeding when either the firmware reports a TPM device
|
|
|
ac3a84 |
or we find a TPM device, let's check that the firmware reports a TPM
|
|
|
ac3a84 |
device and the TPM subsystem is enabled in the kernel.
|
|
|
ac3a84 |
|
|
|
ac3a84 |
To check whether the subsystem enabled, we check if the relevant
|
|
|
ac3a84 |
subdirectory in /sys exists at all.
|
|
|
ac3a84 |
|
|
|
ac3a84 |
(cherry picked from commit 300bba79c22e4be1effe2faad0e59ac725d396a1)
|
|
|
ac3a84 |
|
|
|
ac3a84 |
Related #2138081
|
|
|
ac3a84 |
---
|
|
|
ac3a84 |
man/systemd-creds.xml | 4 ++--
|
|
|
ac3a84 |
src/creds/creds.c | 6 ++++--
|
|
|
ac3a84 |
src/shared/condition.c | 9 ++++-----
|
|
|
ac3a84 |
src/shared/tpm2-util.c | 6 +++++-
|
|
|
ac3a84 |
src/shared/tpm2-util.h | 11 ++++++-----
|
|
|
ac3a84 |
5 files changed, 21 insertions(+), 15 deletions(-)
|
|
|
ac3a84 |
|
|
|
ac3a84 |
diff --git a/man/systemd-creds.xml b/man/systemd-creds.xml
|
|
|
ac3a84 |
index 1e5632e63d..003fbcd463 100644
|
|
|
ac3a84 |
--- a/man/systemd-creds.xml
|
|
|
ac3a84 |
+++ b/man/systemd-creds.xml
|
|
|
ac3a84 |
@@ -175,8 +175,8 @@
|
|
|
ac3a84 |
by the OS kernel drivers and by userspace (i.e. systemd) this prints <literal>yes</literal> and exits
|
|
|
ac3a84 |
with exit status zero. If no such device is discovered/supported/used, prints
|
|
|
ac3a84 |
<literal>no</literal>. Otherwise prints <literal>partial</literal>. In either of these two cases
|
|
|
ac3a84 |
- exits with non-zero exit status. It also shows three lines indicating separately whether drivers,
|
|
|
ac3a84 |
- firmware and the system discovered/support/use TPM2.</para>
|
|
|
ac3a84 |
+ exits with non-zero exit status. It also shows four lines indicating separately whether firmware,
|
|
|
ac3a84 |
+ drivers, the system and the kernel discovered/support/use TPM2.</para>
|
|
|
ac3a84 |
|
|
|
ac3a84 |
<para>Combine with <option>--quiet</option> to suppress the output.</para></listitem>
|
|
|
ac3a84 |
</varlistentry>
|
|
|
ac3a84 |
diff --git a/src/creds/creds.c b/src/creds/creds.c
|
|
|
ac3a84 |
index 5586fd776a..a755a52c34 100644
|
|
|
ac3a84 |
--- a/src/creds/creds.c
|
|
|
ac3a84 |
+++ b/src/creds/creds.c
|
|
|
ac3a84 |
@@ -637,10 +637,12 @@ static int verb_has_tpm2(int argc, char **argv, void *userdata) {
|
|
|
ac3a84 |
|
|
|
ac3a84 |
printf("%sfirmware\n"
|
|
|
ac3a84 |
"%sdriver\n"
|
|
|
ac3a84 |
- "%ssystem\n",
|
|
|
ac3a84 |
+ "%ssystem\n"
|
|
|
ac3a84 |
+ "%ssubsystem\n",
|
|
|
ac3a84 |
plus_minus(s & TPM2_SUPPORT_FIRMWARE),
|
|
|
ac3a84 |
plus_minus(s & TPM2_SUPPORT_DRIVER),
|
|
|
ac3a84 |
- plus_minus(s & TPM2_SUPPORT_SYSTEM));
|
|
|
ac3a84 |
+ plus_minus(s & TPM2_SUPPORT_SYSTEM),
|
|
|
ac3a84 |
+ plus_minus(s & TPM2_SUPPORT_SUBSYSTEM));
|
|
|
ac3a84 |
}
|
|
|
ac3a84 |
|
|
|
ac3a84 |
/* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values
|
|
|
ac3a84 |
diff --git a/src/shared/condition.c b/src/shared/condition.c
|
|
|
ac3a84 |
index 310ffcbdc6..a23d6a3e45 100644
|
|
|
ac3a84 |
--- a/src/shared/condition.c
|
|
|
ac3a84 |
+++ b/src/shared/condition.c
|
|
|
ac3a84 |
@@ -664,14 +664,13 @@ static int condition_test_ac_power(Condition *c, char **env) {
|
|
|
ac3a84 |
}
|
|
|
ac3a84 |
|
|
|
ac3a84 |
static int has_tpm2(void) {
|
|
|
ac3a84 |
- /* Checks whether the system has at least one TPM2 resource manager device, i.e. at least one "tpmrm"
|
|
|
ac3a84 |
- * class device. Alternatively, we are also happy if the firmware reports support (this is to cover
|
|
|
ac3a84 |
- * for cases where we simply haven't loaded the driver for it yet, i.e. during early boot where we
|
|
|
ac3a84 |
- * very likely want to use this condition check).
|
|
|
ac3a84 |
+ /* Checks whether the kernel has the TPM subsystem enabled and the firmware reports support. Note
|
|
|
ac3a84 |
+ * we don't check for actual TPM devices, since we might not have loaded the driver for it yet, i.e.
|
|
|
ac3a84 |
+ * during early boot where we very likely want to use this condition check).
|
|
|
ac3a84 |
*
|
|
|
ac3a84 |
* Note that we don't check if we ourselves are built with TPM2 support here! */
|
|
|
ac3a84 |
|
|
|
ac3a84 |
- return (tpm2_support() & (TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_FIRMWARE)) != 0;
|
|
|
ac3a84 |
+ return FLAGS_SET(tpm2_support(), TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_FIRMWARE);
|
|
|
ac3a84 |
}
|
|
|
ac3a84 |
|
|
|
ac3a84 |
static int condition_test_security(Condition *c, char **env) {
|
|
|
ac3a84 |
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
|
|
ac3a84 |
index 13e92c4144..65e8d48347 100644
|
|
|
ac3a84 |
--- a/src/shared/tpm2-util.c
|
|
|
ac3a84 |
+++ b/src/shared/tpm2-util.c
|
|
|
ac3a84 |
@@ -2189,7 +2189,11 @@ Tpm2Support tpm2_support(void) {
|
|
|
ac3a84 |
if (r != -ENOENT)
|
|
|
ac3a84 |
log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
|
|
|
ac3a84 |
} else if (r == 0) /* populated! */
|
|
|
ac3a84 |
- support |= TPM2_SUPPORT_DRIVER;
|
|
|
ac3a84 |
+ support |= TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER;
|
|
|
ac3a84 |
+ else
|
|
|
ac3a84 |
+ /* If the directory exists but is empty, we know the subsystem is enabled but no
|
|
|
ac3a84 |
+ * driver has been loaded yet. */
|
|
|
ac3a84 |
+ support |= TPM2_SUPPORT_SUBSYSTEM;
|
|
|
ac3a84 |
}
|
|
|
ac3a84 |
|
|
|
ac3a84 |
if (efi_has_tpm2())
|
|
|
ac3a84 |
diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h
|
|
|
ac3a84 |
index 048c28d6ca..c240335ae6 100644
|
|
|
ac3a84 |
--- a/src/shared/tpm2-util.h
|
|
|
ac3a84 |
+++ b/src/shared/tpm2-util.h
|
|
|
ac3a84 |
@@ -137,11 +137,12 @@ typedef struct {
|
|
|
ac3a84 |
typedef enum Tpm2Support {
|
|
|
ac3a84 |
/* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty
|
|
|
ac3a84 |
* much ABI! Hence, be extra careful when changing/extending these definitions. */
|
|
|
ac3a84 |
- TPM2_SUPPORT_NONE = 0, /* no support */
|
|
|
ac3a84 |
- TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
|
|
|
ac3a84 |
- TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
|
|
|
ac3a84 |
- TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
|
|
|
ac3a84 |
- TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM,
|
|
|
ac3a84 |
+ TPM2_SUPPORT_NONE = 0, /* no support */
|
|
|
ac3a84 |
+ TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
|
|
|
ac3a84 |
+ TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
|
|
|
ac3a84 |
+ TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
|
|
|
ac3a84 |
+ TPM2_SUPPORT_SUBSYSTEM = 1 << 3, /* the kernel has the tpm subsystem enabled */
|
|
|
ac3a84 |
+ TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM|TPM2_SUPPORT_SUBSYSTEM,
|
|
|
ac3a84 |
} Tpm2Support;
|
|
|
ac3a84 |
|
|
|
ac3a84 |
Tpm2Support tpm2_support(void);
|