Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/init/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 9 additions & 19 deletions src/init/init.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use qos_core::{
handles::Handles,
io::{SocketAddress, StreamPool, VMADDR_NO_FLAGS},
io::{SocketAddress, VMADDR_NO_FLAGS},
reaper::Reaper,
EPHEMERAL_KEY_FILE, MANIFEST_FILE, PIVOT_FILE, QUORUM_FILE, SEC_APP_SOCK,
EPHEMERAL_KEY_FILE, MANIFEST_FILE, PIVOT_FILE, QUORUM_FILE,
};
use qos_nsm::Nsm;
use qos_system::{dmesg, freopen, get_local_cid, mount, reboot};
Expand All @@ -27,8 +27,8 @@ fn init_rootfs() {
];
for (src, target, fstype, flags, data) in args {
match mount(src, target, fstype, flags, data) {
Ok(()) => dmesg(format!("Mounted {}", target)),
Err(e) => eprintln!("{}", e),
Ok(()) => dmesg(format!("Mounted {target}")),
Err(e) => eprintln!("{e}"),
}
}
}
Expand All @@ -43,7 +43,7 @@ fn init_console() {
for (filename, mode, file) in args {
match freopen(filename, mode, file) {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
Err(e) => eprintln!("{e}"),
}
}
}
Expand All @@ -60,7 +60,7 @@ async fn main() {
dmesg("QuorumOS Booted".to_string());

let cid = get_local_cid().unwrap();
dmesg(format!("CID is {}", cid));
dmesg(format!("CID is {cid}"));

let handles = Handles::new(
EPHEMERAL_KEY_FILE.to_string(),
Expand All @@ -70,20 +70,10 @@ async fn main() {
);

const START_PORT: u32 = 3;
const INITIAL_POOL_SIZE: u8 = 1; // start at pool size 1, grow based on manifest/args as necessary (see Reaper)
let core_pool = StreamPool::new(
SocketAddress::new_vsock(cid, START_PORT, VMADDR_NO_FLAGS),
INITIAL_POOL_SIZE,
)
.expect("unable to create core pool");
let core_socket =
SocketAddress::new_vsock(cid, START_PORT, VMADDR_NO_FLAGS);

let app_pool = StreamPool::new(
SocketAddress::new_unix(SEC_APP_SOCK),
INITIAL_POOL_SIZE, // start at pool size 1, grow based on manifest/args as necessary (see Reaper)
)
.expect("unable to create app pool");

Reaper::execute(&handles, Box::new(Nsm), core_pool, app_pool, None).await;
Reaper::execute(&handles, Box::new(Nsm), core_socket, None).await;

reboot();
}
3 changes: 0 additions & 3 deletions src/integration/examples/boot_enclave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ async fn main() {
fs::create_dir_all(&*tmp).unwrap();

let usock: PathWrapper = "/tmp/enclave-example/example.sock".into();
let app_usock: PathWrapper = "/tmp/enclave-example/example-app.sock".into();
let secret_path: PathWrapper = "/tmp/enclave-example/example.secret".into();
let pivot_path: PathWrapper = "/tmp/enclave-example/example.pivot".into();
let manifest_path: PathWrapper =
Expand Down Expand Up @@ -245,8 +244,6 @@ async fn main() {
.args([
"--usock",
&*usock,
"--app-usock",
&*app_usock,
"--quorum-file",
&*secret_path,
"--pivot-file",
Expand Down
87 changes: 31 additions & 56 deletions src/integration/tests/enclave_app_client_socket_stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ use integration::{
wait_for_usock, PivotSocketStressMsg, PIVOT_SOCKET_STRESS_PATH,
};
use qos_core::{
client::SocketClient,
client::{ClientError, SocketClient},
handles::Handles,
io::{SocketAddress, StreamPool},
io::{IOError, SocketAddress, StreamPool},
protocol::{
msg::ProtocolMsg,
services::boot::{
Manifest, ManifestEnvelope, ManifestSet, Namespace, NitroConfig,
PivotConfig, RestartPolicy, ShareSet,
},
ProtocolError, ProtocolPhase, INITIAL_CLIENT_TIMEOUT,
ProtocolPhase,
},
reaper::{Reaper, REAPER_RESTART_DELAY},
reaper::Reaper,
};
use qos_nsm::mock::MockNsm;
use qos_p256::P256Pair;
Expand Down Expand Up @@ -77,18 +76,13 @@ async fn enclave_app_client_socket_stress() {
handles.put_manifest_envelope(&manifest_envelope).unwrap();
handles.put_quorum_key(&p256_pair).unwrap();

let enclave_pool =
StreamPool::single(SocketAddress::new_unix(ENCLAVE_SOCK)).unwrap();

let app_pool =
StreamPool::single(SocketAddress::new_unix(APP_SOCK)).unwrap();
let enclave_socket = SocketAddress::new_unix(ENCLAVE_SOCK);

tokio::spawn(async move {
Reaper::execute(
&handles,
Box::new(MockNsm),
enclave_pool,
app_pool,
enclave_socket,
// Force the phase to quorum key provisioned so message proxy-ing
// works
Some(ProtocolPhase::QuorumKeyProvisioned),
Expand All @@ -99,56 +93,37 @@ async fn enclave_app_client_socket_stress() {
// Make sure the pivot has some time to start up
wait_for_usock(APP_SOCK).await;

let enclave_client_pool =
StreamPool::single(SocketAddress::new_unix(ENCLAVE_SOCK)).unwrap();
let enclave_client = SocketClient::new(
enclave_client_pool.shared(),
INITIAL_CLIENT_TIMEOUT + Duration::from_secs(3), // needs to be bigger than the slow request below + some time for recovery
let app_client_pool =
StreamPool::single(SocketAddress::new_unix(APP_SOCK)).unwrap();
let app_client = SocketClient::new(
app_client_pool.shared(),
Duration::from_millis(2000),
);

let app_request =
borsh::to_vec(&PivotSocketStressMsg::PanicRequest).unwrap();
let request =
borsh::to_vec(&ProtocolMsg::ProxyRequest { data: app_request })
.unwrap();
let raw_response = enclave_client.call(&request).await.unwrap();
let response = ProtocolMsg::try_from_slice(&raw_response).unwrap();

assert_eq!(
response,
ProtocolMsg::ProtocolErrorResponse(
ProtocolError::AppClientRecvConnectionClosed
)
);
let request = borsh::to_vec(&PivotSocketStressMsg::PanicRequest).unwrap();
let raw_response = app_client.call(&request).await.unwrap_err();

match raw_response {
ClientError::IOError(IOError::RecvConnectionClosed) => {} // expected
_ => panic!("unexpected error received: {:?}", raw_response),
}

// Make sure the pivot has some time to restart
wait_for_usock(APP_SOCK).await;

tokio::time::sleep(REAPER_RESTART_DELAY + Duration::from_secs(1)).await;
// The pivot panicked and should have been restarted.
let app_request =
borsh::to_vec(&PivotSocketStressMsg::OkRequest(1)).unwrap();
let request =
borsh::to_vec(&ProtocolMsg::ProxyRequest { data: app_request })
.unwrap();
let raw_response = enclave_client.call(&request).await.unwrap();
let response = {
let msg = ProtocolMsg::try_from_slice(&raw_response).unwrap();
let data = match msg {
ProtocolMsg::ProxyResponse { data } => data,
x => panic!("Expected proxy response, got {x:?}"),
};
PivotSocketStressMsg::try_from_slice(&data).unwrap()
};
let request = borsh::to_vec(&PivotSocketStressMsg::OkRequest(1)).unwrap();
let raw_response = app_client.call(&request).await.unwrap();
let response = PivotSocketStressMsg::try_from_slice(&raw_response).unwrap();
assert_eq!(response, PivotSocketStressMsg::OkResponse(1));

// Send a request that the app will take too long to respond to
let app_request =
borsh::to_vec(&PivotSocketStressMsg::SlowRequest(5500)).unwrap();
let request =
borsh::to_vec(&ProtocolMsg::ProxyRequest { data: app_request })
.unwrap();
let raw_response = enclave_client.call(&request).await.unwrap();
let response = ProtocolMsg::try_from_slice(&raw_response).unwrap();
assert_eq!(
response,
ProtocolMsg::ProtocolErrorResponse(ProtocolError::AppClientRecvTimeout)
);
borsh::to_vec(&PivotSocketStressMsg::SlowRequest(2100)).unwrap();
let raw_response = app_client.call(&request).await.unwrap_err();

match raw_response {
ClientError::IOError(IOError::RecvTimeout) => {} // expected
_ => panic!("unexpected error received: {:?}", raw_response),
}
}
9 changes: 4 additions & 5 deletions src/integration/tests/qos_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use std::{process::Command, time::Duration};
use integration::PIVOT_OK_PATH;
use qos_test_primitives::{ChildWrapper, PathWrapper};

const TEST_ENCLAVE_SOCKET: &str = "/tmp/async_qos_host_test/enclave.sock";

#[tokio::test]
async fn connects_and_gets_info() {
// prep sock pool dir
std::fs::create_dir_all("/tmp/async_qos_host_test").unwrap();
std::fs::create_dir_all("/tmp/qos_host_test").unwrap();

const TEST_ENCLAVE_SOCKET: &str = "/tmp/qos_host_test/enclave.sock";
let _qos_host: ChildWrapper = Command::new("../target/debug/qos_host")
.arg("--usock")
.arg(TEST_ENCLAVE_SOCKET)
Expand All @@ -29,8 +28,8 @@ async fn connects_and_gets_info() {
assert!(r.is_err()); // expect 500 here

let enclave_socket = format!("{TEST_ENCLAVE_SOCKET}_0"); // manually pick the 1st one
let secret_path: PathWrapper = "/tmp/async_qos_host_test.secret".into();
let manifest_path: PathWrapper = "/tmp/async_qos_host_test.manifest".into();
let secret_path: PathWrapper = "/tmp/qos_host_test.secret".into();
let manifest_path: PathWrapper = "/tmp/qos_host_test.manifest".into();

// For our sanity, ensure the secret does not yet exist
drop(std::fs::remove_file(&*secret_path));
Expand Down
Loading