Skip to content

Commit f49f228

Browse files
authored
Merge pull request #481 from Dstack-TEE/fix/host-api-vsock-only
fix(vmm): Forbid host API listening on non-vsock addresses
2 parents b88777f + 5851019 commit f49f228

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

vmm/src/config.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,22 @@ pub struct HostApiConfig {
409409
pub port: u32,
410410
}
411411

412+
impl HostApiConfig {
413+
/// Validate that the host API address is a vsock address.
414+
/// The host API must only listen on vsock for security reasons.
415+
/// TCP/Unix socket listening is not supported.
416+
pub fn validate(&self) -> Result<()> {
417+
if !self.address.starts_with("vsock:") {
418+
anyhow::bail!(
419+
"Host API address must be a vsock address (e.g., 'vsock:2'), got: '{}'. \
420+
TCP/Unix socket listening is not supported for the host API.",
421+
self.address
422+
);
423+
}
424+
Ok(())
425+
}
426+
}
427+
412428
#[derive(Debug, Clone, Deserialize, Serialize)]
413429
pub struct KeyProviderConfig {
414430
pub enabled: bool,

vmm/src/main.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use path_absolutize::Absolutize;
1515
use rocket::{
1616
fairing::AdHoc,
1717
figment::{providers::Serialized, Figment},
18-
listener::{Bind, DefaultListener},
1918
};
2019
use rocket_apitoken::ApiToken;
2120
use rocket_vsock_listener::VsockListener;
@@ -119,22 +118,13 @@ async fn run_host_api(app: App, figment: Figment) -> Result<()> {
119118
.ignite()
120119
.await
121120
.map_err(|err| anyhow!("Failed to ignite rocket: {err}"))?;
122-
if DefaultListener::bind_endpoint(&ignite).is_ok() {
123-
let listener = DefaultListener::bind(&ignite)
124-
.await
125-
.map_err(|err| anyhow!("Failed to bind host API : {err}"))?;
126-
ignite
127-
.launch_on(listener)
128-
.await
129-
.map_err(|err| anyhow!(err.to_string()))?;
130-
} else {
131-
let listener = VsockListener::bind_rocket(&ignite)
132-
.map_err(|err| anyhow!("Failed to bind host API : {err}"))?;
133-
ignite
134-
.launch_on(listener)
135-
.await
136-
.map_err(|err| anyhow!(err.to_string()))?;
137-
}
121+
// Host API only supports vsock listener (validated at startup)
122+
let listener = VsockListener::bind_rocket(&ignite)
123+
.map_err(|err| anyhow!("Failed to bind host API: {err}"))?;
124+
ignite
125+
.launch_on(listener)
126+
.await
127+
.map_err(|err| anyhow!(err.to_string()))?;
138128
Ok(())
139129
}
140130

@@ -166,6 +156,12 @@ async fn main() -> Result<()> {
166156
let figment = config::load_config_figment(args.config.as_deref());
167157
let config = Config::extract_or_default(&figment)?.abs_path()?;
168158

159+
// Validate host API configuration
160+
config
161+
.host_api
162+
.validate()
163+
.context("Invalid host_api configuration")?;
164+
169165
// Handle commands
170166
match args.command.unwrap_or_default() {
171167
Command::Run(run_args) => {

0 commit comments

Comments
 (0)