Skip to content

Commit 470a0a7

Browse files
committed
fix(simulator): provide TDX configfs without a kernel provider
1 parent d3d24ec commit 470a0a7

2 files changed

Lines changed: 38 additions & 19 deletions

File tree

dstack/tee-simulator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dstack-types.workspace = true
2222
dstack-mr.workspace = true
2323
fuser.workspace = true
2424
libc.workspace = true
25-
nix = { workspace = true, features = ["fs", "mount"] }
25+
nix = { workspace = true, features = ["fs", "mount", "user"] }
2626
sd-notify.workspace = true
2727
sha2.workspace = true
2828
tpm2.workspace = true

dstack/tee-simulator/src/tdx.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use std::ffi::{CString, OsStr};
5+
use std::ffi::OsStr;
66
use std::path::Path;
77
use std::sync::Arc;
88
use std::time::{Duration, SystemTime};
@@ -207,8 +207,8 @@ impl TdxSimulatorFs {
207207
fn new(generator: Arc<TdxGenerator>) -> Result<Self> {
208208
Ok(Self {
209209
state: SimulatorState::new(generator, CCEL_FIXTURE, None)?,
210-
uid: unsafe { libc::geteuid() },
211-
gid: unsafe { libc::getegid() },
210+
uid: nix::unistd::geteuid().as_raw(),
211+
gid: nix::unistd::getegid().as_raw(),
212212
})
213213
}
214214

@@ -448,25 +448,44 @@ pub(crate) fn ensure_configfs_mount(mountpoint: &Path) -> Result<()> {
448448
}
449449

450450
if !mountpoint.is_dir() {
451-
let source = CString::new("configfs")?;
452-
let target = CString::new("/sys/kernel/config")?;
453-
let fstype = CString::new("configfs")?;
454-
let rc = unsafe {
455-
libc::mount(
456-
source.as_ptr(),
457-
target.as_ptr(),
458-
fstype.as_ptr(),
459-
libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC,
460-
std::ptr::null(),
461-
)
462-
};
463-
if rc != 0 {
464-
let error = std::io::Error::last_os_error();
465-
if error.raw_os_error() != Some(libc::EBUSY) {
451+
let flags = nix::mount::MsFlags::MS_NOSUID
452+
| nix::mount::MsFlags::MS_NODEV
453+
| nix::mount::MsFlags::MS_NOEXEC;
454+
if let Err(error) = nix::mount::mount(
455+
Some("configfs"),
456+
"/sys/kernel/config",
457+
Some("configfs"),
458+
flags,
459+
None::<&str>,
460+
) {
461+
if error != nix::errno::Errno::EBUSY {
466462
return Err(error).context("failed to mount configfs");
467463
}
468464
}
469465
}
466+
// configfs rejects arbitrary directories when no kernel TSM provider has
467+
// registered the `tsm` subsystem. In a no-TEE development guest the
468+
// simulator is that provider, so shadow the otherwise-empty configfs with
469+
// a private tmpfs and create the userspace ABI hierarchy there.
470+
if let Err(error) = std::fs::create_dir_all(mountpoint) {
471+
if !matches!(error.raw_os_error(), Some(libc::EPERM) | Some(libc::EACCES)) {
472+
return Err(error)
473+
.with_context(|| format!("failed to create {}", mountpoint.display()));
474+
}
475+
let flags = nix::mount::MsFlags::MS_NOSUID
476+
| nix::mount::MsFlags::MS_NODEV
477+
| nix::mount::MsFlags::MS_NOEXEC;
478+
nix::mount::mount(
479+
Some("dstack-tee-simulator"),
480+
"/sys/kernel/config",
481+
Some("tmpfs"),
482+
flags,
483+
Some("mode=0755"),
484+
)
485+
.context("failed to mount simulator configfs shadow")?;
486+
std::fs::create_dir_all(mountpoint)
487+
.with_context(|| format!("failed to create {}", mountpoint.display()))?;
488+
}
470489
if !mountpoint.is_dir() {
471490
bail!(
472491
"tsm report mountpoint is unavailable: {}",

0 commit comments

Comments
 (0)