dcavalca / rpms / systemd

Forked from rpms/systemd 3 months ago
Clone
ac3a84
From 5b20ba25259da453a2aac5e65978a11bc2d048ed Mon Sep 17 00:00:00 2001
ac3a84
From: Lennart Poettering <lennart@poettering.net>
ac3a84
Date: Tue, 15 Nov 2022 23:01:04 +0100
ac3a84
Subject: [PATCH] tpm2: add some extra validation of device string before using
ac3a84
 it
ac3a84
ac3a84
Let's add some extra validation before constructing and using the .so
ac3a84
name to load. This isn't really security sensitive, given that we
ac3a84
used secure_getenv() to get the device string (and it thus should have
ac3a84
been come from a trusted source) but let's better be safe than sorry.
ac3a84
ac3a84
(cherry picked from commit 50a085143fa8f5dd6b6b3cef8a6ea2ec7c53ed0d)
ac3a84
ac3a84
Related: #2138081
ac3a84
---
ac3a84
 src/shared/tpm2-util.c | 16 ++++++++++++++--
ac3a84
 1 file changed, 14 insertions(+), 2 deletions(-)
ac3a84
ac3a84
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
ac3a84
index 9d73316146..4d0df944a9 100644
ac3a84
--- a/src/shared/tpm2-util.c
ac3a84
+++ b/src/shared/tpm2-util.c
ac3a84
@@ -174,15 +174,27 @@ int tpm2_context_init(const char *device, struct tpm2_context *ret) {
ac3a84
 
ac3a84
                 param = strchr(device, ':');
ac3a84
                 if (param) {
ac3a84
+                        /* Syntax #1: Pair of driver string and arbitrary parameter */
ac3a84
                         driver = strndupa_safe(device, param - device);
ac3a84
+                        if (isempty(driver))
ac3a84
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name is empty, refusing.");
ac3a84
+
ac3a84
                         param++;
ac3a84
-                } else {
ac3a84
+                } else if (path_is_absolute(device) && path_is_valid(device)) {
ac3a84
+                        /* Syntax #2: TPM device node */
ac3a84
                         driver = "device";
ac3a84
                         param = device;
ac3a84
-                }
ac3a84
+                } else
ac3a84
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid TPM2 driver string, refusing.");
ac3a84
+
ac3a84
+                log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver, param);
ac3a84
 
ac3a84
                 fn = strjoina("libtss2-tcti-", driver, ".so.0");
ac3a84
 
ac3a84
+                /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
ac3a84
+                if (!filename_is_valid(fn))
ac3a84
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
ac3a84
+
ac3a84
                 dl = dlopen(fn, RTLD_NOW);
ac3a84
                 if (!dl)
ac3a84
                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());