Due to a significant change in the targeted SELinux policy re-develop
the SELinux policy for swtpm. New rules in swtpm_libvirt.te are needed
when libvirt causes new interactions between swtpm and other types.
Also consider extensions to the SELinux policy previously added due to
domain XML and command lines described in the following patches:
- 63825b296c
- 7dac1dbf6f
Also:
- add rules related to user_tmp_t are due to the following paths being used
in session mode: /run/user/*/libvirt/qemu/run/swtpm
- add rules for swtpm_t accessing qemu_var_run_t file/dir/sockfile
- add rules for swtpm_localca (newly installed F40 system) needed once when
/var/lib/swtpm-localca is empty and files there are created
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity is complaining that thread_busy needs to be locked before
reading. For consistency reasons now also lock thread_busy before reading
it. However, in this case it does not make a difference whether this lock
is held when reading thread_busy since file_ops_lock is held when the
thread_busy flag is set and when it is read with a call to this function
(worker_thread_is_busy). Also while the thread is busy no further commands
can be submitted and it can then reset the thread_busy flag without holding
the file_ops_lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity is complaining that ptm_response in the worker_thread needs to
be locked via the file_ops_lock since it is always locked when
ptm_response is accessed. However, once the thread has been started any
concurrent modification of the ptm_response is prevented with the
thread_busy flag. Therefore, add comments to the thread and ptm_reponse
variable about the locking.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Even though concurrency is not possible before ptm_cuse_lowlevel_main
is called lock the file_ops_lock since Coverity is complaining that
- g_lastCommand in ptm_send_startup
- ptm_repsonse in ptm_send_startup
- tpm_running in main
are not locked. For consistency reasons now also lock these variables
even before activation of concurrency.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Lock the file_ops_lock before reading the tpm_running variable so that
access to access to it is serialized among all possible threads.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Separate the return code returned from change_fd_flags from the current/
original flags of the file descriptor. Return the flags in an optional
integer.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The help screen states that --decryption and --allow-signing require
--tpm2. Enforce this now also when checking flag combination since
neither flags would have any effect for a TPM 1.2.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On error, the caller will call options_value_free() so don't free
ovs->options to avoid a double free.
Fixes: c94a1c4cbd ("swtpm: Fix memory leak in case realloc fails")
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
If we've accepted a connection fd during the main loop, close it once
the main loop terminates.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Test cases using swtpm_localca were failing because swtpm_localca
now picked up the swtpm_cert installed in /usr/bin/swtpm_cert rather
than the one in the PATH. This revert fixes the issue and users will
have to adjust their PATH for out-of-PATH installations.
Resolves: https://github.com/stefanberger/swtpm/issues/829
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
x509 certificate serial numbers can be up to 20 bytes long.
Support this via gmp library.
A serial number must not have its most significant bit set, which
would indicate a negative number. If this is the case, insert '0'
as the first byte.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_localca may also receive the key parameters of other keys than
the ek, therefore introduce the --key alias for --ek and rename the
variable ekparmas to key_params throughout the code.
Extend the man page to describe the --key option as an alias that
is to be used for other public key parameters than specifically those
of an ek.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To make the function creating filenames for keys less ek-specific,
pass the key_type, such as "ek", into this function.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To be able to extend the flags_to_certfiles array with new certifcates
while carrying new flags for new certificate, mask-out exising EK and
platform certificate flags and set the cert_flags variable with it to limit
the view of the entries in the table.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
With a memoryBacking node added to the libvirt domain XML, the unlink
permission on user_tmp_t:sockfile becomes necessary to avoid an avc
denial.
<currentMemory unit='KiB'>2097152</currentMemory>
<memoryBacking>
<hugepages>
<page size='2048' unit='KiB'/>
</hugepages>
</memoryBacking>
Also add the unlink permission to the other occurrences of sock_file.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2165142
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The following command line did not function on an x86_64 host due to missing
SELinux rules:
virt-install -v \
--name fedora-38-aarch64 \
--ram 4096 \
--disk path=fedora-38.img,cache=none \
--nographics \
--os-variant fedora38 \
--import \
--virt-type=qemu \
--arch aarch64 \
--check all=off
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2228423
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_setup and swtpm_localca may be run by a toolstack with log
messages going to a pipe via stdout. Set stdout to be unbuffered to
avoid log messages being lost if the process terminates unexpectedly.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
The --version option was using the wrong goto label error rather than
out to now also exit with exitcode 0.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Close the file descriptors passed to the swtpm process on the parent
side for faster detection of errors in the swtpm process that can
occur if swtpm was passed a profile that it cannot run with.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On busy systems TSC_PhysicalPresence may time out when used with short
duration, so use medium duration instead.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
In case swtpm does not start properly the write() to it may work but
then the read() gets stuck. Detect a failed swtpm by adding a poll()
before the read(). Use some extended durations considering possibly
busy systems.
A terminating swtpm instance can be caused when an unacceptable
profile is passed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the display of long responses that require calling PTM_GET_INFO
multiple times to get parts of the response from increasing offsets
until the whole response has been received.
Long responses are only returned when libtpms has profiles support and
several flags are passed to PTM_GET_INFO.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To support install paths that are not covered by $PATH, and still allow
swtpm_setup and swtpm_localca to find swtpm and swtpm_cert executables,
implement find_program() to prepend the install path if only the program
name is given and otherwise fall back to g_find_program_in_path().
Update the man page stating that swtpm from the installation directory
(BINDIR) is tried to be used before one is attempted to be found in
the PATH.
Resolves: https://github.com/stefanberger/swtpm/issues/795
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The compiler (though wrongly) identifies that the @argv variable
inside of get_swtpm_capabilities() function cam be used
uninitialized. While this is a spurious warning, it's common
practice to initialize g_autofree variables to NULL.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
When opening a log file fails (--log file=/some/path) for
whatever reason the @logfd variable is left set to -1 (the retval
of open()). And due to how _logprintf() is written, the
subsequent attempt to log this failure (logprintf()) returns too
early not printing the useful error.
Therefore, restore the original (CONSOLE_LOGGING) value.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
If swtpm_setup is configured with a log file, it launches swtpm
configured with the same log file. If not, swtpm_setup logs will go to
stdout/stderr and it should configure swtpm to do the same.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Move existing exit label before the return statement and add another
label that includes the free(filebuffer). This avoids a false positive
by 'gcc -fanalyzer' that seems to think that free(filebuffer)
would double-free filebuffer after filebuffer = realloc(tmp, ..)
failure.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Return TPM_FAIL if SWTPM_NVRAM_DecryptData() is called without a key or
if an unhandle type of encryption mode is encountered. Previously this
function would return no error but also would not do any decryption if
no key was provided. Consequently, it would then also not return a byte
array with decrypted data which in turn could led to potential NULL
pointer accesses in subsequent calls. However, all current callers check
whether they have a valid key before they call this function. So the
change is primarily done for static analyzers, such as gcc -fanalyzer,
to ease code analysis.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Extend the capabilities JSON and show the support for the terminate
parameter of the --ctrl option.
Adjust test cases.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement support for the terminate parameter for the control channel
option so that swtpm terminates once the control channel connection is
lost. The primary use case is QEMU that holds the control channel
permanently.
Resolves: https://github.com/stefanberger/swtpm/issues/753
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Set tpm_running = false after TPMLIB_Terminate() call on CMD_SHUTDOWN
to prevent a call to tpmlib_maybe_send_tpm2_shutdown() at the exit
of the mainloop.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Also send TPM2_Shutdown when swtpm is terminated by a signal or due to
lost connection (--terminate option). Previously supported reasons for
sending the TPM2_Shutdown were primarily related to commands sent via
the command channel.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Increase the number of locking retries to 300 over 3 seconds
instead of 100 over 1 second. This gives the failing side more
time to release the lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement CMD_LOCK_STORAGE / PTM_LOCK_STORAGE for a user to be able to
lock the storage of the storage backend (if supported) after its lock
has been released for example when the 'savestate' blob was received
while the TPM state was migrated.
Also adjust test case and extend man pages.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Advertise the capability of supporting the --migration option
in the capabilies JSON that now has the cmdarg-migration verb:
$ swtpm socket --print-capabilities | jq
{
"type": "swtpm",
"features": [
"tpm-1.2",
"tpm-2.0",
"tpm-send-command-header",
"flags-opt-startup",
"flags-opt-disable-auto-shutdown",
"cmdarg-seccomp",
"cmdarg-key-fd",
"cmdarg-pwd-fd",
"cmdarg-print-states",
"cmdarg-migration",
"nvram-backend-dir",
"nvram-backend-file"
],
"version": "0.8.0"
}
Adjust test cases and extend man page.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement the release-lock-outgoing parameter for the --migration option
that causes the storage lock to be released once the 'savestate' blob
transfer has been initiated. To not release the lock too early users must
first get the 'permanent' and 'volatile' state blobs and the 'savestate'
blob must be transferred as the last blob.
When migrating a VM the migration may fail and execution will then resume
on the originating side. In this fallback case the swtpm on the
destination side may need some time to terminate and release the lock.
Therefore, add a loop to the code attempting to re-lock the storage
directory on the source side for a few times until on the destination
side swtpm has released the lock. Retry the locking for 100 times
with 10ms in between. The retries will only ever be necessary if a TPM
command is immediately executed upon resume [this may be difficult
to test]. The negative side effects of this could be that the loop is not
long enough to grab the lock or that a short-duration TPM command will
time out inside the VM due to the retries delaying when it is processed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolves: https://github.com/stefanberger/swtpm/issues/724
Introduce the --migration option along with the 'incoming' parameter
that allows to defer the locking of the storage until either
- the reception of the TPM's state is started
- a TPM command is about to be processed
Note that the reception of CMD_INIT does not enable the storage lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolves: https://github.com/stefanberger/swtpm/issues/724
Move the locking of the storage into tpmlib_start() after the call to
TPMLIB_MainInit() which was previously doing the locking when the prepare
function was called in the SWTPM_NVRAM_Init() callback invoked by
TPMLIB_MainInit().
This allows for conditional locking in tpmlib_start() using a flag later
on.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On OpenBSD openssl/fips.h is not available and FIPS_mode() is not
available, so implement a stub for fips_mode_enabled().
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Advertise the availability of the chroot option with the cmdarg-chroot
verb. Document it in the man page.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add an option to enter a chroot after starting swtpm. This is useful for
sandboxing purposes. When this option is used, it is expected that swtpm
is started as root and the --runas option is used to subsequently drop
privileges (otherwise the chroot could be escaped).
Signed-off-by: Jennifer Herbert <jennifer.herbert@citrix.com>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Address the following compilation error on Debian:
In file included from /usr/include/seccomp.h:821,
from seccomp_profile.c:44:
seccomp_profile.c: In function 'create_seccomp_profile':
seccomp_profile.c:115:9: error: '__NR_mount_setattr' undeclared (first use in this function)
115 | SCMP_SYS(mount_setattr),
| ^~~~~~~~
seccomp_profile.c:115:9: note: each undeclared identifier is reported only once for each function it appears in
seccomp_profile.c:172:9: error: '__NR_quotactl_fd' undeclared (first use in this function)
172 | SCMP_SYS(quotactl_fd),
| ^~~~~~~~
We need to do this since they are defined like this:
#define __SNR_mount_setattr __NR_mount_setattr
#define __SNR_quotactl_fd __NR_quotactl_fd
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Include openssl/opensslv.h to avoid the following error on Ubuntu:
fips.c: In function 'fips_mode_enabled':
fips.c:61:16: error: implicit declaration of function 'EVP_default_properties_is_fips_enabled' [-Werror=implicit-function-declaration]
61 | int mode = EVP_default_properties_is_fips_enabled(NULL);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Resolves: https://github.com/stefanberger/libtpms/issues/345
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Introduce disable-auto-shutdown flag for the --flags option to disable
the sending of TPM2_Shutdown() if swtpm determines that it needs to send
this command to a TPM 2 before device reset or swtpm program termination.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If necessary send a TPM2_Shutdown() command to libtpms before processing
CMD_INIT. However, this is only necessary for a TPM 2 and only if the
TPM2_Shutdown command has not been sent by the client (VM TPM driver) as
the last command as it should do under normal circumstances, for example
upon graceful VM shutdown.
This fixes a bug where abrupt VM resets may trigger the TPM 2's dictionary
attack lockout logic due to the TPM 2 not having received a TPM2_Shutdown
command before it was reset using CMD_INIT for example. An OS driver is
typically supposed to send a TPM2_Shutdown to the TPM 2 but an abrupt VM
reset prevents it.
There are 3 control commands where this needs to be done since they
call TPMLIB_Terminate():
- CMD_STOP:
This command is typically called before setting the state blobs of the
TPM or before configuring the buffer size [QEMU, test cases].
- CMD_INIT:
This command is called for resetting and initializing the TPM 2.
- CMD_SHUTDOWN:
This command is called for a graceful shutdown of the TPM 2.
There are no negative side effects to be expected if TPM2_Shutdown()
is sent before any of these. Also, since none of these are sent before
the state of the TPM is marshalled (for migration for example) migrated
state will not have a TPM2_Shutdown() applied to it (accidentally).
Edk2 sends a sequence of TPM2_Shutdown(SU_STATE) + TPM2_GetRandom()
before suspend-to-ram. Upon wake up a CMD_INIT is sent to the TPM to
reset it, which in this case now requires a TPM2_Shutdown(SU_STATE)
to be sent to the TPM 2 so that certain TPM 2 state is available
again upon resume. To avoid invaliding the SU_STATE, first send a
TPM2_Shutdown(SU_STATE) in *all cases* and only if this fails send a
TPM2_Shutdown(SU_CLEAR). This way the internal state is preserved and
the VM (or user) are expected to use TPM2_Startup(SU_CLEAR) when
staring up the TPM 2 and no previous state needs to be resumed.
Note: The VM's firmware is trusted to use SU_CLEAR under normal circum-
stances and SU_STATE upon resume. So it wouldn't restore the state if
it wasn't needed.
Note: The TPM 2 spec describes the command as follows:
"This command is used to prepare the TPM for a power cycle. The
shutdownType parameter indicates how the subsequent TPM2_Startup() will be
processed.[...]
This command saves TPM state but does not change the state other than the
internal indication that the context has been saved. The TPM shall
continue to accept commands. If a subsequent command changes TPM state
saved by this command, then the effect of this command is nullified. The
TPM MAY nullify this command for any subsequent command rather than check
whether the command changed state saved by this command. If this command
is nullified and if no TPM2_Shutdown() occurs before the next
TPM2_Startup(), then the next TPM2_Startup() shall be
TPM2_Startup(CLEAR)."
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2087538
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Track the last command processed by the TPM so we can determine whether
we may need to send a TPM2_Shutdown() before reset of the TPM 2.
Introduce a variable lastCommand to help track the last command that
was sent to the TPM 2.
In relation to deciding whether a TPM2_Shutdown() needs to be sent, the
tracking of the last-sent command is merely an optimization since for
example a VM with EDK2 will send a TPM2_Shutdown() followed by a
TPM2_GetRandom() upon suspend-to-ram, thus indicating that the last
command was TPM2_GetRandom(). However, under most circumstances it helps
to avoid sending an additional TPM2_Shutdown() if the OS TPM driver sent
one already.
When the suspended VM resume swtpm gets a CMD_INIT that requires swtpm
to decide whether a TPM2_Shutdown() needs to be sent and per the last-sent
command it will then send a TPM2_Shutdown(SU_STATE) as in the abrupt
termination case.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If seccomp-syscalls.h lags behind the syscall definition of __NR_xyz then
the __SNR_xyz #define is not available. Therefore, switch to check for
__SNR_xyz #define because they are available if __NR_xyz is available.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement fips_mode_enabeld() to check whether FIPS is enabledand
use the new function to check for FIPS mode enablement before
trying to disable it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Rename disable_fips_mode() to fips_mode_disable() amd move into
tpmlib_start() after TPMLIB_MainInit(). Clean up the duplicate
prototype.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The project wouldn't compile on my ubuntu 20.04.1 based system with the error message:
```
CC libswtpm_libtpms_la-seccomp_profile.lo
In file included from seccomp_profile.c:44:
seccomp_profile.c: In function ‘create_seccomp_profile’:
seccomp_profile.c:105:9: error: ‘__SNR_fs_mount’ undeclared (first use in this function)
105 | SCMP_SYS(fs_mount),
| ^~~~~~~~
seccomp_profile.c:105:9: note: each undeclared identifier is reported only once for each function it appears in
```
Additionally, there were some duplicates in the profile.
Signed-off-by: Hans Niklas Jacob <hnj@posteo.de>
Extend usage of the FILE_OPS_LOCK to prevent other threads from reading or
writing commands or doing ioctls while the current thread is reading a
response. This prevents a race condition where ptm_read_offset is set to 0
by a thread writing a new command to the device while the current thread
is reading a response from the device and needs this offset.
Resolves: https://github.com/stefanberger/swtpm/issues/725
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Restrict the opening of the CUSE device to one single file descriptor. We
can modify the CUSE TPM in this way since the kernel's /dev/tpm0 cannot be
opened multiple times, either, and the CUSE TPM should behave in the same
way.
Adjust test the partial reads case to only open CUSE device file once by
using a python program. Close the open file descriptor 100 before using
swtpm_ioctl to avoid failures.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Revert the change from the previous patch that shows an error when
TPMLIB_ChooseTPMVersion fails but rather ignore the error as before.
If a TPM 2 is supported then tpm-2.0 capability verb will be shown
and if a TPM 1.2 is supported then tpm-1.2 will be shown, thus
allowing someone reading the JSON to determine what is supported.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
All callers to capabilities_print_json() call TPMLIB_ChooseTPMVersion
right before. Move it into the function now and check the return
code.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement get_swtpm_capabilities() and call it from two existing functions
that now become a lot simpler.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Commit 6559a902 implemented support for the startup-xyz flags for the CUSE
interface but the capability has not been advertised.
Adjust test cases to reflect the new verb being shown for
--print-capabilities.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Replace the hardcoded install path in src/selinux/swtpm.fc and
src/selinux/swtpmcuse.fc with @prefix@ and append .in to these files so
that they are generated when running configure.
Add the selinux policy input files with their suffix to the CLEANFILES
variable so they get cleaned up and 'make distcheck' works.
Resolves: https://github.com/stefanberger/swtpm/issues/711
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
While libtpms does not provide any means to disable FIPS-disabled crypto
algorithms from being used, work around the issue by simply disabling the
FIPS mode of OpenSSL if it is enabled. If it cannot be disabled, exit
swtpm with a failure message that it cannot be disabled. If FIPS mode
was successfully disabled, print out a message as well.
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2090219
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not use TPM2_ALG_SHA1 anymore as parameter to TPM2_IncrementalSelfTest()
so that this also works when SHA1 support in libtpms is runtime-disabled.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Handle the case where an unknown blobtype is given and therefore
cannot be translated to a filename and blobname is NULL. Previously
this would have lead to an error when trying to read the file, now
we handle the failure case earlier.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To avoid an overflowing expression cast '1' to uint64_t before shifting
it and assigning it to a uint64_t variable. In practice this kind of
overflow would never happen because there aren't that many available
PCR banks.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize the 'res' variable at the beginning of the function
even though this wouldn't be necessary in this case.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a comment stating that failure to read the optsfile is not an
issue since the optsfile does not need to exist.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize pubek_len even though it isn't necessary to do so since
it will be initialized in the first function to which it is passed.
However, Coverity complains about pubek_len passed to print_as_hex()
not being initialized, even though this is not possible.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid a memory leaks if --tcp is provided multiple times by freeing
the previously allocated memory in the tcp_hostname variable.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Close the file descriptor at the end of the main function.
To avoid closing random file descriptors initialize it with -1.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid memory leaks if one of the parameters --tcp, --tpm-device,
or --unix was passed multiple times by freeing the previously
parsed value.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid memory leaks if one of the parameters --modulus, --ecc-x,
or --ecc-y was passed multiple times by freeing the previously
parsed value.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Commit 2d3deaef29 forgot to move the check for whether the lock file has
already been opened into the new function opening the lock file and there-
fore the lock file is now opened whenever swtpm gets a PTM_INIT. This fix
prevents the reopening of the lockfile if it has already been opened.
Otherwise many PTM_INIT's will lead to failure since no more files can
be opened.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Remove support for TPM state files that didn't have the header
because they were created some time before v0.1.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To be able to test-compile with include/swtpm/tpm_ioctl.h in configure.ac
move the definition of __USE_LINUX_IOCTL_DEFS out of the configure script
into the header file so that the #define is there when needed. In the
configure.ac script the CFLAGS were extended only after the test-compiling
to determine the HARDENING_CFLAGS and the test-compilation failed on Cygwin
(only) since the tpm_ioctl.h didn't compile because of this missing
#define.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Instead of uint32_t use uint64_t's for accumulating needed buffer sizes
that are calculated by adding uint32_t length indicators. Use the uint64_t
to check for excessively large buffer sizes that could cause an integer
overflow if uint32_t was used.
This patch addresses the case where a user passes an old version of TPM
state file to swtpm for reading and the file is 4GB in size and thus can
cause an integer overflow in this particular function.
Otherwise, the previous fix to tlv_data_find_tag() protects swtpm from
integer overflows and later out-of-bound accesses when the TPM state is
initially read from a file (assuming the state file has a header, which
is the case since swtpm 0.1). If an excessively large buffer was passed
to libtpms, it would reject it since it would never be able to take in
that much data.
Data written to the file are coming from libtpms that we can trust in
terms of length indicators.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To avoid an integer wrap-around use uint64_t for 'offset' so that adding
an untrusted 32-bit number will allow for comparison against the trusted
'buffer_len' 32-bit number:
if (offset + td->tlv.length > buffer_len)
return NULL;
This avoids possible out-of-bound accesses and crashes when reading
specially crafted TPM state input data that have a tlv.length that is so
large that is causes an integer overflow.
Resolves: https://github.com/stefanberger/swtpm/issues/678
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The port being parsed must be given as unsigned int so that the comparison
of *tcp_port >= 65536 also filters out negative numbers passed via the
command line. Previously one could pass -1 and swtpm_bios would try to
connect.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The port being parsed must be given as unsigned int so that the comparison
of *tcp_port >= 65536 also filters out negative numbers passed via the
command line. Previously one could pass -1 and swtpm_ioctl would try to
connect to port 65535.
Resolves: https://github.com/stefanberger/swtpm/issues/679
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
With relative paths being used the chdir("/") in daemonize_finish() will
cause file access errors.
Fixes: 98d1d12 ("swtpm: Make --daemon not racy")
Resolves: https://github.com/stefanberger/swtpm/issues/671
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_localca v0.5 supported resolution of environment variables for
the swtpm-localca.conf configuration file. This functionality was lost
during the port to 'C' in v0.6. This patch now re-implements it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolves: https://github.com/stefanberger/swtpm/issues/663
Avoid trying to create TPM certificates while the issuer certificate has
not been created, yet (in a 2nd step).
To resolve this do not just test for availability of the signing key, which
is created first, but also test for the issuer certifcate, which is created
in a 2nd step when the local CA is created. If either one is missing,
attempt to create the CA.
Resolves: https://github.com/stefanberger/swtpm/issues/644
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This fix addresses Coverity issue CID 375869.
Check the header size indicated in the header of the state against the
expected size and return an error code in case the header size indicator
is different. There was only one header size so far since blobheader was
introduced, so we don't need to deal with different sizes.
Without this fix a specially craft header could have cause out-of-bounds
accesses on the byte array containing the swtpm's state.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This fix addresses Coverity issue CID 370783.
Check for an unreasonable number of PCR banks returned from command sent
to swtpm. Limit the number of PCR banks that can be returned to '20',
which is more than enough.
Previously we may not have sanitized the variable correctly but safeguards
were in place:
Even if the 16 bit variable count was the maximum possible (0xffff) we
should be able to allocate the all_pcr_banks array of string pointers.
Safeguards to not overstep the parsed array are in place in the loop
that's entered afterwards where the count variable serves as a limit
for the loop.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Free the allocated string array in case of failure.
Existing callers auto-free the array already, so there's no memory leak,
but it is better to free it in the function where it is allocated.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Cast the '1' to uint64_t as suggested by Coverity (CID 375870).
Since 'j' is always less than '32', the previous code was correct as
well.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement tpmlib_choose_tpm_version() that reports an error when an un-
supported version is chosen. Have it used by existing code where possible.
If TPM 1.2 is not supported by libtpms, the following message is now
displayed:
swtpm: Error: TPM 1.2 is not supported by libtpms.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2024583
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Get rid of a Coverity complaint by not assigning the same pointer
to the result of g_strchomp() as the parameter to the function.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Get rid of a Coverity complaint by not assigning the same pointer
to the result of g_strchomp() as the parameter to the function.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the following compilation error occurring on 32bit machines:
swtpm_nvstore_linear_file.c: In function 'SWTPM_NVRAM_LinearFile_Mmap':
swtpm_nvstore_linear_file.c:58:20: error: comparison of integer expressions of different signedness: '__off_t' {aka 'long int'} and 'unsigned int' [-Werror=sign-compare]
58 | if (st.st_size >= (uint32_t)sizeof(struct nvram_linear_hdr)) {
| ^~
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add support for --reconfigure option for the swtpm_setup to be able to
change the active PCR banks. This option only works with --tpm2 and does
not allow to pass several other options such --create-ek or
--create-ek-cert or --create-platform-cert that would alter the state of
the TPM 2 in other ways.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Certain characters are not accepted by gnutls when creating the
subject with the 'CN' from the vmid, so we have to replace those
characters with another one, such as '_'.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Write the active_pcr_banks into swtpm_setup.conf with the default
PCR banks from the configure script.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If the user did not provide the PCR banks to activate through the command
line options, try to read it from the config file and if nothing is found
there, fall back to the DEFAULT_PCR_BANKS as set during configure time.
Move the check for the PCR banks after the access check to the
configuration file.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add an option that allows for the configuration of the default PCR bank
to use. This was currently hard coded to sha256 and now may be passed
via this option. The fallback is still sha256. Valid PCR bank names are
sha1, sha256, sha384, and sha512. The passed list must be a comma-
separated list of the valid PCR bank names.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_setup.conf has traditionally pointed to
/usr/share/swtpm/swtpm-localca for create_certs_tool but since
/usr/bin/swtpm_localca is now available, have newly created
config files point to this executable instead.
Since there are possibly many swtpm_setup.conf out there pointing
to /usr/share/swtpm/swtpm-localca, we have to still install
swtm_localca there as well and package it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
We cannot currently fsync on the TPM's state file and the dir since this
takes too long and commands in a VM may time out. The reason for this is
that the TPM 2 code occasionally writes the permanent state out even on
commands like TPM2_PCR_Extend that must not take a long time.
See explanation for this in the libtpms PR https://github.com/stefanberger/libtpms/pull/274 .
We will re-enable this feature in 'a while' once the updated libtpms
version has been made more widely available.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix issue #591 by initializing the variables swtpm_has_tpm2 and
swtpm_has_tpm12.
swtpm_setup.c:1178:31: note: 'swtpm_has_tpm2' was declared here
gboolean swtpm_has_tpm12, swtpm_has_tpm2;
^~~~~~~~~~~~~~
swtpm_setup.c:1019:5: error: 'swtpm_has_tpm12' may be used uninitialized in this function [-Werror=maybe-uninitialized]
printf("{ \"type\": \"swtpm_setup\", "
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"\"features\": [ %s%s\"cmdarg-keyfile-fd\", \"cmdarg-pwdfile-fd\", \"tpm12-not-need-root\""
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
It is possible to start swtpm with this command line even though
neither storage nor communication channels have been provided.
./src/swtpm/swtpm socket --flags not-need-init,startup-clear
Since sending a startup message to the TPM will cause it to
want to store permanent state, we have to handle the case when
no storage backend was given and therefore the backend_uri
is NULL.
Previously the above command line caused a NULL pointer exception
but now handles this case with the following output:
swtpm: SWTPM_NVRAM_Init: Missing backend URI.
swtpm: Error: Could not initialize libtpms.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Rather than having the CA certificates, that are created on the fly,
expire in 10 years, have them not expire at all.
Also create TPM certificates that don't expire and extend a test
case for this.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement support for skipping over creating the files
if any one of the config files already exist.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement the option --create-config-files to create config files
for swtpm_setup and swtpm-localca for a user account. The files will
be created under the $XDG_CONFIG_HOME or $HOME/.config directories.
This option supports optional arguments 'overwrite' to allow overwriting
existing config files as well as the optional argument 'root' to create
config files under root's home directory. Both options can be passed
by separating them with a ','.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Display the --print-states capability in the --print-capabilites
output as cmdarg-print-states.
Document availability in the man page.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Cygwin internally uses the Windows API call FlushViewOfFile that
seems to not like to be called with an excessive number of bytes.
Instead, call it with length = 0 so that 'the file is flushed from
the base address to the end of the mapping' and then msync() succeeds.
Source:
https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-flushviewoffile
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use the pidfile filename rather than the fd because Cygwin for example
does not seem to support passed file descriptors and also OpenBSD
does not pass some test cases because of this.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The header file endian.h does not exists everywhere, so we have to
use system_dependencies.h to get something similar on all systems.
Some compilers, such as gcc on FreeBSD, are picky about unused
function parameters, so we have to decorate the unused ones
with SWTPM_ATTR_UNUSED.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The header file fs/linux.h only exists on Linux but we can also
use sys/mount.h, which also exists on Cygwin and the BSDs.
Only support block devices if BLKGETSIZE64 is defined.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Abstract away implementation specific code for handling TPM state in
swtpm_setup. The current code for handling directories is moved to
'swtpm_backend_dir.c'.
Where possible, the input argument is simply passed verbatim as
'backend-uri' to swtpm.
No functional change intended, aside from supporting 'dir://' as
optional prefix. The checks for lock-file accessibility are moved to
check_access(), but that shouldn't affect anything AFAICT.
Signed-off-by: Stefan Reiter <stefan@pimaker.at>
This avoids issues with state backends where we don't have a convenient
directory for a pidfile available.
Signed-off-by: Stefan Reiter <stefan@pimaker.at>
...and use delete_swtpm_statefiles instead. This function iterates the
folder instead of just deleting one file, but since it is already called
before the init call guarded here, it can only affect files created by
this run anyway.
Note that delete_state had slightly different return semantics, but it
doesn't matter, as the return value is ignored here anyway (best effort
cleanup).
Signed-off-by: Stefan Reiter <stefan@pimaker.at>
Implements a second abstraction layer as an NVRAM storage backend: The
"linear" backend stores data in a simple format that can contain
multiple files (multiple TPM states and numbers) in one linear address
space. This can then be mapped to files or other "block-device-like"
interfaces using nvram_linear_file_ops implementations.
A simple one using mmap is provided with the URI type "file://".
Does not support any locking at the moment, users must ensure exclusive
access themselves.
Signed-off-by: Stefan Reiter <stefan@pimaker.at>
Only recent libvirt versions have the patch for the AppArmor profile for
libvirt to allow fsync after opening a directory for reading. Rather
than failing hard on the open-directory-for-reading error, log it once
and continue and do not try it again after.
This patch addresses the problems seen on Ubuntu related to an older
version of libvirt without the AppArmor profile update.
- issue #484
- issue #549
- issue #559
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Only recent libvirt versions have the patch for the AppArmor profile
for libvirt to allow fsync on dir and directory. Rather than failing
hard on this error, log it once and continue and do not try fsync
again after.
This patch addresses the problems seen on Ubuntu related to an older
version of libvirt without the AppArmor profile update.
- issue #484
- issue #549
- issue #559
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
FreeBSD may return errno EINVAL beside ENOENT once there are no more
entries in a directory to walk over. It claims that readdir() follows
the getdirentries() return codes, which do include EINVAL but not
ENOENT. But ENOENT is also being used.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use return rather than exit() when returning from main so that g_autofree'd
variables can be freed.
This resolves issue #568 that occurs with clang only.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use return rather than exit() when returning from main so that g_autofree'd
variables can be freed.
This resolves issue #568 that occurs with clang only.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Whenever swtpm_setup is executed with --logfile option, forward the
option to swtpm (--log file=...). This helps debugging swtpm
initialization issues.
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Add the size of the type state to the --print-states output and switch
back to a JSON object when enumerating the blobs.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Search for all the state files not just the permanent state and
when printing the JSON use the abstracted names rather than concrete
filenames that are only valid for the dir backend but will likely
not exist in other backends.
Adjust swtpm_setup to search for the abstracted name and also
adjust the error message to print out the abstracted name.
Adjust the test cases.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement a CheckState interface function for checking for the
TPM_PERMANENT_ALL_NAME blog. The dirctory backend does a simple stat on the
file without actually reading it, which otherwise may require the (correct)
key if it was encrypted.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Remove all interface functions from swtpm_nvstore_dir.h and make them
static in swtpm_nvstore_dir.c. This way we avoid direct calls to these
functions from elsewhere.
Move the declaration of the interface structure into swtpm_nvstore.h
to get rid of swtpm_nvstore_dir.h entirely.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If is_chardev is false, then we have a buffersize of 4096 bytes per
the following statement:
322 if (!is_chardev)
323 buffersize = 4096;
With this we end up in the following if branch:
384 if (buffersize) {
385 /* continue with the read interface */
[...]
418
419 break;
420 } else {
Per the break in line 419 we leave the loop, thus cannot reach the
statement we remove:
423 if (!is_chardev)
424 break;
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Don't set flag MAIN_LOOP_FLAG_END_ON_HUP in the handler for control
channel command CMD_SET_DATAFD, since this caused the swtpm daemon to
unconditionally terminate when the data channel connection dropped.
Removing the flag allows this behavior to be controlled by the user
via the --terminate command-line switch, as it was meant to be.
Signed-off-by: Nick Chevsky <nchevsky@users.noreply.github.com>
Use the EVP_CIPHER implementation for the AES CBC computations. This
API has been supported already in OpenSSL 1.1.x for sure and is also
not deprecated in OpenSSL 3.0.
This now resolves issue #538.
We can build src/swtpm without having to suppress deprecated API warnings.
Since this is the last issue related to OpenSSL deprecated APIs, we don't
need to suppress any OpenSSL 3.0 deprecated API warnings anymore.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add an implementation of SWTPM_HMAC using non-deprecated APIs when
compiling with OpenSSL 3.0.
This partially addresses issue #538.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use the (undocumented) OPENSSL_SUPPRESS_DEPRECATED to suppress the
deprecated API warnings when compiling swtpm and swtpm_setup with
OpenSSL 3.0.0 replacing the global -Wno-deprecated-declarations.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Instead of directly accessing TPM state store file, use --print-states
to check if there is existing state file or not. This can reduce TPM
state directory dependencies of swtpm_setup.
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
--print-states reports TPM states stored in --tpmstate backend.
This feature is supposed to be used by swtpm_setup for checking TPM state
existence.
Sample output is as follows:
$ swtpm socket --print-states --tpmstate dir=/tmp --tpm2 | jq .
{
"type": "swtpm",
"states": [
{
"name": "tpm2-00.permall"
}
]
}
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Introduce GetFilepathForName() and use it to get a rooted state file
path instead of existing GetFilenameForName().
Move GetFilenameForName() to swtpm_nvstore.c so that other TPM state
store backend can use it.
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Currently swtpm_setup saves ek.cert and platform.cert to TPM state
directory and removes them later. As the usage of these files are
temporary, temp directory can be used for this purpose. This reduces
dependencies on TPM state dir, which is convenient for pluggable state
store (https://github.com/stefanberger/swtpm/issues/461).
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Fix the following compilation issue:
swtpm_nvstore_dir.c: In function 'SWTPM_NVRAM_Validate_Dir':
swtpm_nvstore_dir.c:149:86: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
TPM_DEBUG("SWTPM_NVRAM_Validate_Dir: Rooted state path %s\n", tpm_state_path);
^
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
glib's (v2.68) g_thread_pool_new() calls the syscall sched_setattr(),
which we must allow to avoid termination of the CUSE TPM.
This patch resolves issue #520.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add an options to specify pluggable backend URI.
Ex:
--tpmstate backend-uri=dir://<path_to_dir>
Backend URI is specific to each backend plugin which points to the
location of the NVRAM files.
Currently, "dir" is the only one available backend. In this case
backend-uri should be a path to the directory where files are stored.
This option is designed to compatible with existing "dir" option.
If "dir" is specified, swtpm prioritize "dir" ignoring "backend-uri".
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Related GH issue: https://github.com/stefanberger/swtpm/issues/461
This patch adds an abstraction layer to NVRAM state store implementation
for pluggable storage backends. No functional changes are intended in
this change. The default state store backend ("dir backend") keeps
current behavior.
To make swtpm ready for pluggable store, this patch moves file related
operations to the seperate file (swtpm_nvstore_dir.c) and defined the
interface for plugins (nvram_backend_ops in swtpm_nvstore.h). The
interface can be used by each plugin which will be added later.
With the interface, each plugin can access its "backend_uri" which
points to the location of the backend storage, for example S3 bucket
URL or iSCSI URL, and decide how it stores TPM state data.
Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
Implement get_supported_tpm_versions to get swtpm's support for TPM 1.2
and TPM 2 and use it error out in case user choose a TPM version that
is not supported. Also display the supported TPM versions in the
capabilites JSON.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>