naccyde / rpms / systemd

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