diff options
author | David Tolnay <dtolnay@chromium.org> | 2019-03-01 16:18:44 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-03-02 17:41:27 -0800 |
commit | 41a6f84d857c5b5f6ee612f9654c87dca10f3b54 (patch) | |
tree | 3b4c8aaa8087c76cbecc9e8c1244c47b6329f46d /src/linux.rs | |
parent | 48c4829540b04fb1a6f9ea0343f6c68b8c72606e (diff) | |
download | crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar.gz crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar.bz2 crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar.lz crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar.xz crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.tar.zst crosvm-41a6f84d857c5b5f6ee612f9654c87dca10f3b54.zip |
tpm: Store TPM state under /run/vm
When running in multiprocess mode, such as on a device, TPM state gets placed in /run/vm/tpm.{pid} (e.g. /run/vm/tpm.22726) where pid is the pid of the original crosvm process. The TPM simulator will write a single file called NVChip of size 16384 bytes into this directory. The directory and NVChip file will have uid and pid set to crosvm. When running without multiprocess mode / without minijail / probably in cros_sdk, TPM state is placed in /tmp/tpm-simulator as before. The /run/vm directory is not present under cros_sdk. Will follow up with a separate CL to remove the TPM state directory at crosvm exit. Tested by running the following on a grunt board (Barla) in dev mode: sudo crosvm run \ --root rootfs.ext4 \ --socket crosvm.sock \ --seccomp-policy-dir seccomp \ --software-tpm \ -p init=/bin/bash \ -p panic=-1 \ vmlinux.bin and confirming that /dev/tpm0 and /dev/tpmrm0 are present in the VM. BUG=chromium:921841 TEST=manual testing on grunt Change-Id: I1868896b9eb6f510d8b97022ba950b3604d9d40b Reviewed-on: https://chromium-review.googlesource.com/1496910 Commit-Ready: David Tolnay <dtolnay@chromium.org> Tested-by: David Tolnay <dtolnay@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r-- | src/linux.rs | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/src/linux.rs b/src/linux.rs index 6d09cbf..a8f7ae9 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -19,7 +19,7 @@ use std::thread; use std::thread::JoinHandle; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use libc::{self, c_int}; +use libc::{self, c_int, gid_t, uid_t}; use audio_streams::DummyStreamSource; use byteorder::{ByteOrder, LittleEndian}; @@ -312,11 +312,48 @@ fn create_devices( #[cfg(feature = "tpm")] { + use std::ffi::CString; + use std::fs; + use std::process; + use sys_util::chown; + if cfg.software_tpm { - let tpm_box = Box::new(devices::virtio::Tpm::new()); + let tpm_storage: PathBuf; + let mut tpm_jail = simple_jail(&cfg, "tpm_device.policy")?; + + match &mut tpm_jail { + Some(jail) => { + // Create a tmpfs in the device's root directory for tpm + // simulator storage. The size is 20*1024, or 20 KB. + jail.mount_with_data( + Path::new("none"), + Path::new("/"), + "tmpfs", + (libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC) as usize, + "size=20480", + )?; + + let crosvm_ids = add_crosvm_user_to_jail(jail, "tpm")?; + + let pid = process::id(); + let tpm_pid_dir = format!("/run/vm/tpm.{}", pid); + tpm_storage = Path::new(&tpm_pid_dir).to_owned(); + fs::create_dir_all(&tpm_storage)?; + let tpm_pid_dir_c = CString::new(tpm_pid_dir).expect("no nul bytes"); + chown(&tpm_pid_dir_c, crosvm_ids.uid, crosvm_ids.gid)?; + + jail.mount_bind(&tpm_storage, &tpm_storage, true)?; + } + None => { + // Path used inside cros_sdk which does not have /run/vm. + tpm_storage = Path::new("/tmp/tpm-simulator").to_owned(); + } + } + + let tpm = devices::virtio::Tpm::new(tpm_storage); devs.push(VirtioDeviceStub { - dev: tpm_box, - jail: simple_jail(&cfg, "tpm_device.policy")?, + dev: Box::new(tpm), + jail: tpm_jail, }); } } @@ -665,12 +702,17 @@ fn create_devices( Ok(pci_devices) } +struct Ids { + uid: uid_t, + gid: gid_t, +} + // Set the uid/gid for the jailed process and give a basic id map. This is // required for bind mounts to work. fn add_crosvm_user_to_jail( jail: &mut Minijail, feature: &str, -) -> std::result::Result<(), Box<Error>> { +) -> std::result::Result<Ids, Box<Error>> { let crosvm_user_group = CStr::from_bytes_with_nul(b"crosvm\0").unwrap(); let crosvm_uid = match get_user_id(&crosvm_user_group) { @@ -696,7 +738,10 @@ fn add_crosvm_user_to_jail( jail.gidmap(&format!("{0} {0} 1", crosvm_gid)) .map_err(Error::SettingGidMap)?; - Ok(()) + Ok(Ids { + uid: crosvm_uid, + gid: crosvm_gid, + }) } fn raw_fd_from_path(path: &PathBuf) -> std::result::Result<RawFd, Box<Error>> { |