tpm2: add SWTPM fallback test, fixes and hardening (#42722)

This commit is contained in:
Lennart Poettering
2026-06-25 17:13:03 +02:00
committed by GitHub
10 changed files with 228 additions and 21 deletions
+26 -9
View File
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <unistd.h>
#include "sd-json.h"
@@ -8,6 +9,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "json-util.h"
#include "log.h"
#include "memfd-util.h"
@@ -17,6 +19,7 @@
#include "string-util.h"
#include "strv.h"
#include "swtpm-util.h"
#include "sync-util.h"
static int swtpm_find_best_profile(const char *swtpm_setup, char **ret) {
int r;
@@ -135,6 +138,10 @@ int manufacture_swtpm(const char *state_dir, const char *secret) {
assert(state_dir);
_cleanup_close_ int state_dir_fd = open(state_dir, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (state_dir_fd < 0)
return log_error_errno(errno, "Failed to open TPM state directory '%s': %m", state_dir);
_cleanup_free_ char *swtpm_setup = NULL;
r = find_executable("swtpm_setup", &swtpm_setup);
if (r < 0)
@@ -151,9 +158,9 @@ int manufacture_swtpm(const char *state_dir, const char *secret) {
if (!localca_conf)
return log_oom();
r = write_string_filef(
localca_conf,
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_TRUNCATE|WRITE_STRING_FILE_MKDIR_0755,
r = write_string_filef_at(
state_dir_fd, "swtpm-localca.conf",
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC,
"statedir = %1$s\n"
"signingkey = %1$s/signing-private-key.pem\n"
"issuercert = %1$s/issuer-certificate.pem\n"
@@ -166,12 +173,12 @@ int manufacture_swtpm(const char *state_dir, const char *secret) {
if (!localca_options)
return log_oom();
r = write_string_file(
localca_options,
r = write_string_file_at(
state_dir_fd, "swtpm-localca.options",
"--platform-manufacturer systemd\n"
"--platform-version 2.1\n"
"--platform-model swtpm\n",
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_TRUNCATE|WRITE_STRING_FILE_MKDIR_0755);
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
if (r < 0)
return log_error_errno(r, "Failed to write swtpm-localca.options: %m");
@@ -184,9 +191,9 @@ int manufacture_swtpm(const char *state_dir, const char *secret) {
if (!setup_conf)
return log_oom();
r = write_string_filef(
setup_conf,
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_TRUNCATE|WRITE_STRING_FILE_MKDIR_0755,
r = write_string_filef_at(
state_dir_fd, "swtpm_setup.conf",
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC,
"create_certs_tool = %1$s\n"
"create_certs_tool_config = %2$s\n"
"create_certs_tool_options = %3$s\n",
@@ -234,5 +241,15 @@ int manufacture_swtpm(const char *state_dir, const char *secret) {
_exit(EXIT_FAILURE);
}
/* Persist swtpm_setup's freshly created TPM state before writing the completion marker. */
r = syncfs_path(state_dir_fd, NULL);
if (r < 0)
return log_error_errno(r, "Failed to sync TPM state directory: %m");
/* Marker, written last, signals that manufacturing completed successfully. */
_cleanup_close_ int marker_fd = xopenat(state_dir_fd, SWTPM_MANUFACTURED_MARKER, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOFOLLOW);
if (marker_fd < 0)
return log_error_errno(marker_fd, "Failed to write '%s' marker: %m", SWTPM_MANUFACTURED_MARKER);
return 0;
}
+5
View File
@@ -1,4 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* Marker file written into the TPM state directory once swtpm_setup has successfully created the TPM state.
* It is written last, so its presence reliably means a complete TPM was manufactured, rather than a manufacture
* that was interrupted halfway through. */
#define SWTPM_MANUFACTURED_MARKER ".manufactured"
int manufacture_swtpm(const char *state_dir, const char *secret);