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 channel_read_with_downgrade to SDK #1837

Merged
merged 1 commit into from
Feb 9, 2021
Merged
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
41 changes: 40 additions & 1 deletion examples/abitest/module_0/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use oak::{
ChannelReadStatus, OakError, OakStatus,
};
use oak_abi::{
label::Label,
label::{confidentiality_label, top, Label},
proto::oak::application::{
node_configuration::ConfigType, ConfigMap, CryptoConfiguration, NodeConfiguration,
RoughtimeClientConfiguration, StorageProxyConfiguration,
Expand Down Expand Up @@ -243,6 +243,10 @@ impl OakAbiTestService for FrontendNode {
"ChannelReadOrphan",
(Self::test_channel_read_orphan, Count::Unchanged),
);
tests.insert(
"ChannelReadWithDowngrade",
(Self::test_channel_read_with_downgrade, Count::Unchanged),
);
tests.insert(
"ChannelWriteRaw",
(Self::test_channel_write_raw, Count::Unchanged),
Expand Down Expand Up @@ -1075,6 +1079,41 @@ impl FrontendNode {
Ok(())
}

fn test_channel_read_with_downgrade(&mut self) -> TestResult {
let mut buffer = Vec::<u8>::with_capacity(5);
let test_msg = vec![0x01, 0x02, 0x03];

let (public_out_channel, public_in_channel) =
oak::channel_create("Public test channel", &Label::public_untrusted())
.expect("could not create channel");

// Test that [`oak::channel_read_with_downgrade`] is successful.
oak::channel_write(public_out_channel, &test_msg, &[]).expect("could not write to channel");
expect_eq!(
Ok(()),
oak::channel_read_with_downgrade(public_in_channel, &mut buffer, &mut vec![])
);
expect_eq!(Ok(()), oak::channel_close(public_out_channel.handle));
expect_eq!(Ok(()), oak::channel_close(public_in_channel.handle));

let (private_out_channel, private_in_channel) =
oak::channel_create("Private test channel", &confidentiality_label(top()))
.expect("could not create channel");

// Test that [`oak::channel_read_with_downgrade`] returns
// [`OakStatus::ErrPermissionDenied`].
oak::channel_write(private_out_channel, &test_msg, &[])
.expect("could not write to channel");
expect_eq!(
Err(OakStatus::ErrPermissionDenied),
oak::channel_read_with_downgrade(private_in_channel, &mut buffer, &mut vec![])
);
expect_eq!(Ok(()), oak::channel_close(private_out_channel.handle));
expect_eq!(Ok(()), oak::channel_close(private_in_channel.handle));

Ok(())
}

fn test_channel_write_raw(&mut self) -> TestResult {
let (out_channel, in_channel, _) = channel_create_raw();

Expand Down
4 changes: 2 additions & 2 deletions examples/aggregator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ gcloud monitoring dashboards list
1. Build the example, including the Wasm module
1. Get module SHA256 hash via
`sha256sum examples/aggregator/bin/aggregator.wasm`
1. Push the module to GS via `./scripts/push-example -e aggregator`
1. Push the module to GS via `./scripts/push_example -e aggregator`
1. Fix the URL and hash in [`./oak_app_manifest.toml`](./oak_app_manifest.toml)
1. Fix module hash in the following files:

- `examples/aggregator/config.toml`
- `examples/aggregator/client/cpp/aggregator.cc`
- `examples/aggregator/module/android/cpp/client.cc`
- `examples/aggregator/client/android/cpp/client.cc`
2 changes: 1 addition & 1 deletion examples/aggregator/client/android/cpp/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ JNIEXPORT void JNICALL Java_com_google_oak_aggregator_MainActivity_createChannel
// The particular value corresponds to the hash on the `aggregator.wasm` line in
// https://github.com/project-oak/oak/blob/hashes/reproducibility_index.
oak::label::Label label = oak::WebAssemblyModuleHashLabel(
absl::HexStringToBytes("29fbf24bb76ab71b81bee0ce9cc1d995191a5f814ee7e5a1e04e227176779ffe"));
absl::HexStringToBytes("3fe9708f70d8b63c51ed9c179928f7a48e2d92fcd90e6a4bf87e1572838e2975"));
kChannel = Aggregator::NewStub(oak::ApplicationClient::CreateChannel(
address, oak::ApplicationClient::GetTlsChannelCredentials(ca_cert), label));
JNI_LOG("gRPC channel has been created");
Expand Down
2 changes: 1 addition & 1 deletion examples/aggregator/client/cpp/aggregator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ int main(int argc, char** argv) {
// https://github.com/project-oak/oak/blob/hashes/reproducibility_index.
// TODO(#1674): Add appropriate TLS endpoint tag to the label as well.
oak::label::Label label = oak::WebAssemblyModuleHashLabel(
absl::HexStringToBytes("29fbf24bb76ab71b81bee0ce9cc1d995191a5f814ee7e5a1e04e227176779ffe"));
absl::HexStringToBytes("3fe9708f70d8b63c51ed9c179928f7a48e2d92fcd90e6a4bf87e1572838e2975"));
// Connect to the Oak Application.
auto stub = Aggregator::NewStub(oak::ApplicationClient::CreateChannel(
address, oak::ApplicationClient::GetTlsChannelCredentials(ca_cert), label));
Expand Down
2 changes: 1 addition & 1 deletion examples/aggregator/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
grpc_server_listen_address = "[::]:8080"
backend_server_address = "https://localhost:8888"
aggregator_module_hash = "29fbf24bb76ab71b81bee0ce9cc1d995191a5f814ee7e5a1e04e227176779ffe"
aggregator_module_hash = "3fe9708f70d8b63c51ed9c179928f7a48e2d92fcd90e6a4bf87e1572838e2975"
2 changes: 1 addition & 1 deletion examples/aggregator/oak_app_manifest.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "aggregator"

[modules]
app = { external = { url = "https://storage.googleapis.com/oak-modules/aggregator/29fbf24bb76ab71b81bee0ce9cc1d995191a5f814ee7e5a1e04e227176779ffe", sha256 = "29fbf24bb76ab71b81bee0ce9cc1d995191a5f814ee7e5a1e04e227176779ffe" } }
app = { external = { url = "https://storage.googleapis.com/oak-modules/aggregator/3fe9708f70d8b63c51ed9c179928f7a48e2d92fcd90e6a4bf87e1572838e2975", sha256 = "3fe9708f70d8b63c51ed9c179928f7a48e2d92fcd90e6a4bf87e1572838e2975" } }
2 changes: 1 addition & 1 deletion examples/private_set_intersection/oak_app_manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ signature_manifests = [
[modules]
app = { path = "examples/private_set_intersection/bin/private_set_intersection.wasm" }
# TODO(865): Use locally built module once reproducibility is fixed.
handler = { external = { url = "https://storage.googleapis.com/oak-modules/private_set_intersection_handler/08ac29c2e8fc7de860750457f1e97decc3f0089711e5efd574453085706b0a42", sha256 = "08ac29c2e8fc7de860750457f1e97decc3f0089711e5efd574453085706b0a42" } }
handler = { external = { url = "https://storage.googleapis.com/oak-modules/private_set_intersection_handler/46ee3f4e2db7ff0789af779e134c8b1848763f0bd5fb830a300ab3fd0efb2bf0", sha256 = "46ee3f4e2db7ff0789af779e134c8b1848763f0bd5fb830a300ab3fd0efb2bf0" } }
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ f41SClNtR4i46v2Tuh1fQLbt/ZqRr1lENajCW92jyP4=
-----END PUBLIC KEY-----

-----BEGIN SIGNATURE-----
OHHEdnjxlKwAQU6dwiI8ZVRfSZ4VOttRWvube1z+/E78ey0NDLwqtfRJ1ZoNc0oY
ufKZSPJZsUG0spGOYd7qBQ==
TfYigVCdqcjW7xJReS+S5/XMfkQCpulBf1nrHLkFHRoMpiWw8IbFfdVgVAlwfvmx
i6JWeP5SnSfO2MyXaqm0AQ==
-----END SIGNATURE-----

-----BEGIN HASH-----
CKwpwuj8fehgdQRX8el97MPwCJcR5e/VdEUwhXBrCkI=
Ru4/Ti23/weJr3eeE0yLGEh2PwvV+4MKMAqz/Q77K/A=
-----END HASH-----
14 changes: 14 additions & 0 deletions experimental/oak_async/tests/fake_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ pub extern "C" fn channel_read(
})
}

/// Stub function necessary for Oak ABI.
#[no_mangle]
pub extern "C" fn channel_read_with_downgrade(
_handle: Handle,
_buf: *mut u8,
_size: usize,
_actual_size: *mut u32,
_handle_buf: *mut u8,
_handle_count: u32,
_actual_handle_count: *mut u32,
) -> u32 {
0
}

type ReadyChannelData = VecDeque<Result<Vec<u8>, OakStatus>>;

std::thread_local! {
Expand Down
4 changes: 4 additions & 0 deletions oak/module/oak_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ oak_abi::OakStatus channel_read(oak_abi::Handle handle, uint8_t* buff, size_t us
uint32_t* actual_size, oak_abi::Handle* handle_buff,
size_t handle_count, uint32_t* actual_handle_count);
WASM_IMPORT("oak")
oak_abi::OakStatus channel_read_with_downgrade(oak_abi::Handle handle, uint8_t* buff, size_t usize,
uint32_t* actual_size, oak_abi::Handle* handle_buff,
size_t handle_count, uint32_t* actual_handle_count);
WASM_IMPORT("oak")
oak_abi::OakStatus channel_write(oak_abi::Handle handle, uint8_t* buff, size_t usize,
uint8_t* handle_buff, size_t handle_count);
WASM_IMPORT("oak")
Expand Down
12 changes: 12 additions & 0 deletions oak_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ extern "C" {
actual_handle_count: *mut u32,
) -> u32;

/// The same as [`channel_read`](#method.channel_read), but also applies the current Node's
/// downgrade privilege when checking IFC restrictions.
pub fn channel_read_with_downgrade(
handle: u64,
buf: *mut u8,
size: usize,
actual_size: *mut u32,
handle_buf: *mut u8,
handle_count: u32,
actual_handle_count: *mut u32,
) -> u32;

/// Write a message to a channel.
///
/// Write `size` bytes of data from `buf`, together with `handle_count` handles from
Expand Down
2 changes: 1 addition & 1 deletion oak_runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ impl Runtime {
}

/// Returns the effective label for `initial_label` in the context of the Node, taking into
/// acount whether the downgrade privilege should be applied.
/// account whether the downgrade privilege should be applied.
fn get_effective_label(
&self,
node_id: NodeId,
Expand Down
138 changes: 119 additions & 19 deletions oak_runtime/src/node/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

use crate::{
node::{ConfigurationError, NodeIsolation},
LabelReadStatus, NodeMessage, NodePrivilege, NodeReadStatus, RuntimeProxy, SignatureTable,
Downgrading, LabelReadStatus, NodeMessage, NodePrivilege, NodeReadStatus, RuntimeProxy,
SignatureTable,
};
use byteorder::{ByteOrder, LittleEndian};
use log::{debug, error, info, trace, warn};
Expand Down Expand Up @@ -47,16 +48,17 @@ const RANDOM_GET: usize = 2;
const CHANNEL_CLOSE: usize = 3;
const CHANNEL_CREATE: usize = 4;
const CHANNEL_CREATE_WITH_DOWNGRADE: usize = 5;
const HANDLE_CLONE: usize = 14;
const CHANNEL_WRITE: usize = 6;
const CHANNEL_WRITE_WITH_DOWNGRADE: usize = 7;
const CHANNEL_READ: usize = 8;
const WAIT_ON_CHANNELS: usize = 9;
const CHANNEL_LABEL_READ: usize = 10;
const NODE_LABEL_READ: usize = 11;
const NODE_PRIVILEGE_READ: usize = 12;
const HANDLE_CLONE: usize = 6;
const CHANNEL_WRITE: usize = 7;
const CHANNEL_WRITE_WITH_DOWNGRADE: usize = 8;
const CHANNEL_READ: usize = 9;
const CHANNEL_READ_WITH_DOWNGRADE: usize = 10;
const WAIT_ON_CHANNELS: usize = 11;
const CHANNEL_LABEL_READ: usize = 12;
const NODE_LABEL_READ: usize = 13;
const NODE_PRIVILEGE_READ: usize = 14;
// TODO(#817): remove this; we shouldn't need to have WASI stubs.
const WASI_STUB: usize = 13;
const WASI_STUB: usize = 15;

// Type aliases for positions and offsets in Wasm linear memory. Any future 64-bit version
// of Wasm would use different types.
Expand Down Expand Up @@ -457,14 +459,88 @@ impl WasmInterface {
actual_handle_count_addr
);

self.channel_read_util(
reader_handle,
dest,
dest_capacity,
actual_length_addr,
handles_dest,
handles_capacity,
actual_handle_count_addr,
Downgrading::No,
)
}

/// Corresponds to the host ABI function [`channel_read_with_downgrade`](https://github.com/project-oak/oak/blob/main/docs/abi.md#channel_read_with_downgrade).
#[allow(clippy::too_many_arguments)]
fn channel_read_with_downgrade(
&mut self,
reader_handle: oak_abi::Handle,

dest: AbiPointer,
dest_capacity: AbiPointerOffset,
actual_length_addr: AbiPointer,

handles_dest: AbiPointer,
handles_capacity: AbiPointerOffset,
actual_handle_count_addr: AbiPointer,
) -> Result<(), OakStatus> {
trace!(
"{}: channel_read_with_downgrade({}, {}, {}, {}, {}, {}, {})",
self.pretty_name,
reader_handle,
dest,
dest_capacity,
actual_length_addr,
handles_dest,
handles_capacity,
actual_handle_count_addr
);

self.channel_read_util(
reader_handle,
dest,
dest_capacity,
actual_length_addr,
handles_dest,
handles_capacity,
actual_handle_count_addr,
Downgrading::Yes,
)
}

/// Helper function used by [`channel_read`](https://github.com/project-oak/oak/blob/main/docs/abi.md#channel_read)
/// and [`channel_read_with_downgrade`](https://github.com/project-oak/oak/blob/main/docs/abi.md#channel_read_with_downgrade).
#[allow(clippy::too_many_arguments)]
fn channel_read_util(
&mut self,
reader_handle: oak_abi::Handle,

dest: AbiPointer,
dest_capacity: AbiPointerOffset,
actual_length_addr: AbiPointer,

handles_dest: AbiPointer,
handles_capacity: AbiPointerOffset,
actual_handle_count_addr: AbiPointer,

downgrade: Downgrading,
) -> Result<(), OakStatus> {
self.validate_ptr(dest, dest_capacity)?;
self.validate_ptr(handles_dest, handles_capacity * 8)?;

let msg = self.runtime.channel_try_read_message(
reader_handle,
dest_capacity as usize,
handles_capacity as usize,
)?;
let msg = match downgrade {
Downgrading::Yes => self.runtime.channel_try_read_message_with_downgrade(
reader_handle,
dest_capacity as usize,
handles_capacity as usize,
),
Downgrading::No => self.runtime.channel_try_read_message(
reader_handle,
dest_capacity as usize,
handles_capacity as usize,
),
}?;

let (actual_length, actual_handle_count) = match &msg {
None => (0, 0),
Expand All @@ -478,7 +554,7 @@ impl WasmInterface {
.set(actual_length_addr, raw_writer)
.map_err(|err| {
error!(
"{}: channel_read(): Unable to write actual length into guest memory: {:?}",
"{}: channel_read_util(): Unable to write actual length into guest memory: {:?}",
self.pretty_name, err
);
OakStatus::ErrInvalidArgs
Expand All @@ -490,7 +566,7 @@ impl WasmInterface {
.set(actual_handle_count_addr, raw_writer)
.map_err(|err| {
error!(
"{}: channel_read(): Unable to write actual handle count into guest memory: {:?}",
"{}: channel_read_util(): Unable to write actual handle count into guest memory: {:?}",
self.pretty_name, err
);
OakStatus::ErrInvalidArgs
Expand All @@ -500,7 +576,7 @@ impl WasmInterface {
Some(NodeReadStatus::Success(msg)) => {
self.get_memory().set(dest, &msg.bytes).map_err(|err| {
error!(
"{}: channel_read(): Unable to write destination buffer into guest memory: {:?}",
"{}: channel_read_util(): Unable to write destination buffer into guest memory: {:?}",
self.pretty_name, err
);
OakStatus::ErrInvalidArgs
Expand All @@ -516,7 +592,7 @@ impl WasmInterface {
.set(handles_dest, &raw_writer)
.map_err(|err| {
error!(
"{}: channel_read(): Unable to write destination buffer into guest memory: {:?}",
"{}: channel_read_util(): Unable to write destination buffer into guest memory: {:?}",
self.pretty_name, err
);
OakStatus::ErrInvalidArgs
Expand Down Expand Up @@ -874,6 +950,15 @@ impl wasmi::Externals for WasmInterface {
args.nth_checked(5)?,
args.nth_checked(6)?,
)),
CHANNEL_READ_WITH_DOWNGRADE => map_host_errors(self.channel_read_with_downgrade(
args.nth_checked(0)?,
args.nth_checked(1)?,
args.nth_checked(2)?,
args.nth_checked(3)?,
args.nth_checked(4)?,
args.nth_checked(5)?,
args.nth_checked(6)?,
)),
CHANNEL_LABEL_READ => map_host_errors(self.channel_label_read(
args.nth_checked(0)?,
args.nth_checked(1)?,
Expand Down Expand Up @@ -1045,6 +1130,21 @@ fn oak_resolve_func(
Some(ValueType::I32),
),
),
"channel_read_with_downgrade" => (
CHANNEL_READ_WITH_DOWNGRADE,
wasmi::Signature::new(
&[
ValueType::I64, // handle
ABI_USIZE, // buf
ABI_USIZE, // size
ABI_USIZE, // actual_size (out)
ABI_USIZE, // handle_buf
ValueType::I32, // handle_count
ABI_USIZE, // actual_handle_count (out)
][..],
Some(ValueType::I32),
),
),
"wait_on_channels" => (
WAIT_ON_CHANNELS,
wasmi::Signature::new(
Expand Down
Loading