Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vTPM support for Linux #1591

Closed
wants to merge 16 commits into from
Closed

Conversation

stefanberger
Copy link
Contributor

@stefanberger stefanberger commented Sep 8, 2017

This patch series adds vTPM support for Linux to libcontainer.

The functionality is based on a recently added vtpm_proxy driver, which is becoming
available in Linux 4.8. The driver provides /dev/vtpmx, on which an ioctl is called
that spawns a TPM device in the host's /dev directory and returns an anonymous file-
descriptor on which a TPM emulator can listen for TPM commands. If we for example
created /dev/tpm12 on the host we make this device available as /dev/tpm0 inside the
container. We also add its major and minor numbers to the device cgroup.

We implement a VTPM class that allows us to create the device and starts a TPM
emulator 'swtpm', to which it passes the anonymous file descriptor.
Besides that, the user can choose to have the vTPM create certificates in a step
that simulates TPM manufacturing. We do this by calling the external swtpm_setup
program, which is part of the swtpm project.

VTPM support is added inside the JSON configuration as follows:

[...]
    "linux": {
        "resources": {
            "devices": [
                {
                    "allow": false,
                    "access": "rwm"
                }
            ] ,
            "vtpms": [
                {
                    "statePath": "/tmp/tpm-1",
                    "createCerts": true,
                },
            ]
        },

This JSON markup makes a single TPM available inside the created container.

o The statPath parameter indicates the directory where the TPM emulator 'swtpm'
writes the state of the TPM device to.
o The createCerts parameter indicates that certificates for the TPM are
to be created.

The swtpm project is available here : https://github.com/stefanberger/swtpm
The libtpms project is available here: https://github.com/stefanberger/libtpms

Signed-off-by: Stefan Berger [email protected]

@stefanberger
Copy link
Contributor Author

stefanberger commented Sep 8, 2017

This is a continuation of the PR #1082 that cannot be reopened anymore.

@deitch
Copy link
Contributor

deitch commented Sep 8, 2017

Thanks for reopening.

@@ -320,6 +320,13 @@ type LinuxNetwork struct {
Priorities []LinuxInterfacePriority `json:"priorities,omitempty"`
}

// VTPM definition
type VTPM struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crosbymichael How do you feel about including changes to vendor/?
@stefanberger Is there a runtime-spec PR open about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyphar I opened opencontainers/runtime-spec#920 for vTPM support

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's current status of opencontainers/runtime-spec#920 ?

cc @vbatts

@lukehinds
Copy link

are you working on this still @stefanberger ? I don't have reviewer access, but from what I have looked at, the patch looks in good shape.

@JAORMX
Copy link

JAORMX commented Nov 20, 2019

Seems there are merge conflicts here. Anybody working on this still?

@stefanberger stefanberger force-pushed the vtpm branch 6 times, most recently from 64e9c4c to 23b636d Compare December 31, 2019 02:08
@stefanberger
Copy link
Contributor Author

I rebased this on the latest master and am now creating the vTPM devices at higher layer in utils_linux.go, which makes cleanup in the error case less invasive.

@stefanberger stefanberger force-pushed the vtpm branch 2 times, most recently from 756521d to 2a798ce Compare December 31, 2019 12:49
@stefanberger
Copy link
Contributor Author

This now works right out of the box with a recent kernel on Fedora 31. The kernel-modules-extra package for 5.3.16-300.fc31 has the necessary kernel module.

Install the packages:
dnf -y install swtpm-tools

Create a spec:
/usr/loca/sbinl/runc spec

Add the following modifications to the spec in config.json:

                                        "allow": false,
                                        "access": "rwm"
                                }
+                       ],
+                       "vtpms": [
+                               {
+                                       "statepath": "/tmp/myvtpm1",
+                                       "vtpmversion": "2"
+                               }
                        ]
                },
                "namespaces": [

Run a container:

/usr/local/sbin/runc run test
sh-5.0# ls -l /dev/tpm*
crw-------. 1 root root 253,     1 Jan  2 14:59 /dev/tpm0
crw-------. 1 root root 253, 65537 Jan  2 14:59 /dev/tpmrm0

@stefanberger stefanberger force-pushed the vtpm branch 3 times, most recently from 58eae95 to a548859 Compare January 3, 2020 19:05
@stefanberger
Copy link
Contributor Author

I just extended the series with patches for running the TPM emulator swtpm with an AppArmor profilevcreated on the fly. I had tried to use the existing function apparmor.ApplyProfile() that tries to apply a profile via writing to /proc/self/attr/exec, though this created 50% failures. I have to write to /proc/<tid>/attr/exec to get 100% success.

@stefanberger stefanberger force-pushed the vtpm branch 3 times, most recently from 1cb507d to 98f315b Compare January 6, 2020 14:13
@stefanberger
Copy link
Contributor Author

stefanberger commented Jan 6, 2020

Running swtpm with an SELinux label has now also landed:

# ps auxZ | grep swtpm
system_u:system_r:container_t:s0:c494,c987 root 1149416 1.2  0.0 7680 3104 ?     Ss   09:20   0:00 swtpm chardev --tpmstate dir=/var/lib/runc/myvtpm1 --daemon --fd 5 --pid file=/var/lib/runc/myvtpm1/swtpm.pid --log file=/var/lib/runc/myvtpm1/swtpm.log --runas 0 --tpm2 --locality reject-locality-4,allow-set-locality --flags not-need-init
# sudo ls -lZ /var/lib/runc/myvtpm
total 20
drwxr-x---. 2 root root system_u:object_r:container_file_t:s0:c927,c931 4096 Jan  6 09:21 .
drwxr-xr-x. 3 root root unconfined_u:object_r:var_lib_t:s0              4096 Jan  4 19:46 ..
-rw-r-----. 1 root root system_u:object_r:container_file_t:s0:c927,c931    0 Jan  6 09:21 .lock
-rw-r--r--. 1 root root system_u:object_r:container_file_t:s0:c927,c931   75 Jan  4 19:46 swtpm.log
-rw-r--r--. 1 root root system_u:object_r:container_file_t:s0:c927,c931    7 Jan  6 09:21 swtpm.pid
-rw-r-----. 1 root root system_u:object_r:container_file_t:s0:c927,c931 1187 Jan  6 09:21 tpm2-00.permall

@stefanberger stefanberger force-pushed the vtpm branch 2 times, most recently from b7e7aa7 to d8f8e71 Compare January 6, 2020 14:55
defer vtpmx.Close()

if err := ioctl(uintptr(vtpmx.Fd()), cmd, msg); err != nil {
return fmt.Errorf("VTPM: vtpmx ioctl failed: %v", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

errors.Wrap

@AkihiroSuda
Copy link
Member

Seems we need to wait to see how opencontainers/runtime-spec#920 will settle

@stefanberger stefanberger force-pushed the vtpm branch 5 times, most recently from d34a3bb to 8fa2643 Compare July 6, 2020 15:50
kolyshkin and others added 5 commits July 6, 2020 15:04
Remove whitespace at EOL

Signed-off-by: Kir Kolyshkin <[email protected]>
1. When using `runc`, we should check `$status` and not `$?`.

2. Before exit code check, let's (try to) show errors from CRIU log.

Signed-off-by: Kir Kolyshkin <[email protected]>
Signed-off-by: Mrunal Patel <[email protected]>
full diff: cilium/ebpf@a9f01ed...1c8d4c9

drops support for go1.12, and removes dependency on the golang.org/x/xerrors
transitional package.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
@stefanberger stefanberger force-pushed the vtpm branch 2 times, most recently from ab0db75 to b8c570c Compare July 6, 2020 19:10
This patch adds vTPM support for Linux to libcontainer.

The functionality is based on a recently added vtpm_proxy driver, which
is becoming available in Linux 4.8. The driver provides /dev/vtpmx, on
which an ioctl is called that spawns a TPM device in the host's /dev
directory and returns an anonymous file-descriptor on which a TPM emulator
can listen for TPM commands. If we for example created /dev/tpm12 on the
host we make this device available as /dev/tpm0 inside the container. We
also add its major and minor numbers to the device cgroup.

We implement a VTPM class that allows us to create the device and starts
a TPM emulator 'swtpm', to which it passes the anonymous file descriptor.
Besides that, the user can choose to have the vTPM create certificates in
a step that simulates TPM manufacturing. We do this by calling the external
swtpm_setup program, which is part of the swtpm project.

VTPM support is added inside the JSON configuration as follows:

[...]
	"linux": {
		"resources": {
			"devices": [
				{
					"allow": false,
					"access": "rwm"
				}
			] ,
			"vtpms": [
				{
					"statePath": "/tmp/tpm-1",
					"createCerts": true
				},
			]
		},
[...]

This JSON markup makes a single TPM available inside the created container.

o The statPath parameter indicates the directory where the TPM emulator
  'swtpm' writes the state of the TPM device to.
o The createCerts parameter indicates that certificates for the
  TPM are to be created.

The current implementation does not support checkpointing, so checkpointing
of a container with an attached vTPM is prevented.

The swtpm project is available here  : https://github.com/stefanberger/swtpm
The libtpms project is available here: https://github.com/stefanberger/libtpms

Signed-off-by: Stefan Berger <[email protected]>
We need to implement ApplyProfileThread() to apply a profile
via /proc/self-thread/attr/exec rather than /proc/self/attr/exec
otherwise we get (~50%) failures trying to write the profile
to /proc/self/attr/exec. When using self-thread we get 100% success.

Signed-off-by: Stefan Berger <[email protected]>
Create an AppArmor profile and apply it so that swtpm runs with an AppArmor
profile.

Signed-off-by: Stefan Berger <[email protected]>
On systems supporting SELinux run swtpm with an SELinux label
applied. Also label the required files in the state directory.

Signed-off-by: Stefan Berger <[email protected]>
Add test cases for testing TPM 1.2 and TPM 2 by creating, stopping,
restarting, and destroying it.

Signed-off-by: Stefan Berger <[email protected]>
Call 'swtpm chardev --print-capabilities' to get the supported capabilites
from swtpm. An JSON object is printed by swtpm that we unmarshal and
we pick the 'features' part from it that is an array of strings indicating
what this version of swtpm supports. This option was added in v0.2.
For older versions of swtpm we return an empty array.

Signed-off-by: Stefan Berger <[email protected]>
We need to startup the TPM as part of starting swtpm so that the Linux
driver can successfully send its initial command to the vTPM and does
not log a failure and then do the startup itself.

Signed-off-by: Stefan Berger <[email protected]>
This patch adds support for encrypting the vTPM state by allowing
a user to pass a password to swtpm_setup and swtpm.

Signed-off-by: Stefan Berger <[email protected]>
Add /sys/devices/virtual/tpm to the mask paths to avoid isolation
issues via sysfs for TPM 1.2

Signed-off-by: Stefan Berger <[email protected]>
Put vTPMs into a container's cgroup to limit their CPU usage.

Signed-off-by: Stefan Berger <[email protected]>
@mfranczy
Copy link

@stefanberger are you still working on this PR?

@kolyshkin
Copy link
Contributor

Since opencontainers/runtime-spec#920 is closed, we should close this one as well.

@kolyshkin kolyshkin closed this Jun 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.