sirenia: Use serde_bytes where appropriate.
Vec<u8> is often inefficient in serde, but serde_bytes provides a way of
labeling these as byte fields so they can be handled efficiently.
Also fix a clippy error where a mutable reference to a vector could be
replaced by a slice.
BUG=b:233694042,b:239114202
TEST=cargo test --workspace --all-features
Cq-Depend: chromium:3780891
Change-Id: Ic6fa83a2420064cf52cf882c59d8fc1f807d7bbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3781443
Reviewed-by: Paramjit Oberoi <psoberoi@google.com>
Tested-by: Allen Webb <allenwebb@google.com>
Commit-Queue: Allen Webb <allenwebb@google.com>
diff --git a/sirenia/Cargo.toml b/sirenia/Cargo.toml
index 4589656..0032a92 100644
--- a/sirenia/Cargo.toml
+++ b/sirenia/Cargo.toml
@@ -71,6 +71,7 @@
libsirenia = { path = "libsirenia" } # provided by ebuild
log = "0.4.0"
serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
serde_json = "1.0.64"
stderrlog = "0.5.0"
thiserror = "1.0.20"
diff --git a/sirenia/libsirenia/Cargo.toml b/sirenia/libsirenia/Cargo.toml
index ed5147c..ea445c2 100644
--- a/sirenia/libsirenia/Cargo.toml
+++ b/sirenia/libsirenia/Cargo.toml
@@ -25,5 +25,6 @@
openssl = "0.10.40"
sirenia-rpc-macros = { path = "sirenia-rpc-macros" } # provided by ebuild
serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
serde_json = "1.0.64"
thiserror = "1.0.20"
diff --git a/sirenia/libsirenia/src/communication/mod.rs b/sirenia/libsirenia/src/communication/mod.rs
index 85e8cd8..1277533 100644
--- a/sirenia/libsirenia/src/communication/mod.rs
+++ b/sirenia/libsirenia/src/communication/mod.rs
@@ -26,6 +26,7 @@
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde::Serialize;
+use serde_bytes::ByteBuf;
use thiserror::Error as ThisError;
use crate::sys::eagain_is_ok;
@@ -188,7 +189,8 @@
pub const SHA256_SIZE: usize = 32;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
-pub struct Digest([u8; SHA256_SIZE]);
+#[serde(try_from = "ByteBuf")]
+pub struct Digest(#[serde(serialize_with = "serde_bytes::serialize")] [u8; SHA256_SIZE]);
impl Deref for Digest {
type Target = [u8; SHA256_SIZE];
@@ -212,6 +214,14 @@
}
}
+impl TryFrom<ByteBuf> for Digest {
+ type Error = TryFromSliceError;
+
+ fn try_from(value: ByteBuf) -> StdResult<Self, Self::Error> {
+ Ok(Digest(value.deref().try_into()?))
+ }
+}
+
impl fmt::Display for Digest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.map(|x| format!("{:02x}", x)).join(""))
diff --git a/sirenia/libsirenia/src/communication/tee_api.rs b/sirenia/libsirenia/src/communication/tee_api.rs
index 0220965..ad437d6 100644
--- a/sirenia/libsirenia/src/communication/tee_api.rs
+++ b/sirenia/libsirenia/src/communication/tee_api.rs
@@ -6,6 +6,7 @@
use std::result::Result as StdResult;
+use serde_bytes::ByteBuf;
use sirenia_rpc_macros::sirenia_rpc;
use crate::communication::persistence;
@@ -13,7 +14,7 @@
#[sirenia_rpc]
pub trait TeeApi<E> {
// Storage.
- fn read_data(&mut self, id: String) -> StdResult<(persistence::Status, Vec<u8>), E>;
+ fn read_data(&mut self, id: String) -> StdResult<(persistence::Status, ByteBuf), E>;
fn remove(&mut self, id: String) -> StdResult<persistence::Status, E>;
fn write_data(&mut self, id: String, data: Vec<u8>) -> StdResult<persistence::Status, E>;
}
diff --git a/sirenia/libsirenia/src/communication/trichechus.rs b/sirenia/libsirenia/src/communication/trichechus.rs
index bc9d89f..c635796 100644
--- a/sirenia/libsirenia/src/communication/trichechus.rs
+++ b/sirenia/libsirenia/src/communication/trichechus.rs
@@ -13,6 +13,7 @@
use log::info;
use serde::Deserialize;
use serde::Serialize;
+use serde_bytes::ByteBuf;
use sirenia_rpc_macros::sirenia_rpc;
use thiserror::Error as ThisError;
@@ -83,7 +84,7 @@
#[error()]
fn get_apps(&mut self) -> StdResult<AppManifest, E>;
#[error()]
- fn get_logs(&mut self) -> StdResult<Vec<Vec<u8>>, E>;
+ fn get_logs(&mut self) -> StdResult<Vec<ByteBuf>, E>;
fn prepare_manatee_memory_service_socket(&mut self, port_number: u32) -> StdResult<(), E>;
diff --git a/sirenia/manatee-runtime/Cargo.toml b/sirenia/manatee-runtime/Cargo.toml
index 0f44511..3c508fb 100644
--- a/sirenia/manatee-runtime/Cargo.toml
+++ b/sirenia/manatee-runtime/Cargo.toml
@@ -18,5 +18,6 @@
log = "0.4.0"
once_cell = "1.7.2"
serde = { version = "1.0.114", features = ["derive"] }
+serde_bytes = "0.10.0"
stderrlog = "0.5.0"
sync = { path = "../../../platform/crosvm/common/sync" } # provided by ebuild
diff --git a/sirenia/manatee-runtime/src/storage/mod.rs b/sirenia/manatee-runtime/src/storage/mod.rs
index 49ba310..79fa060 100644
--- a/sirenia/manatee-runtime/src/storage/mod.rs
+++ b/sirenia/manatee-runtime/src/storage/mod.rs
@@ -56,7 +56,7 @@
fn read_raw(&mut self, id: &str) -> Result<Vec<u8>> {
// TODO: Log the rpc error.
match self.rpc.lock().read_data(id.to_string()) {
- Ok((Status::Success, res)) => Ok(res),
+ Ok((Status::Success, res)) => Ok(res.into()),
Ok((Status::IdNotFound, _)) => Err(Error::IdNotFound(id.to_string())),
Ok((Status::Failure, _)) | Ok((Status::CryptoFailure, _)) => Err(Error::ReadData(None)),
Err(err) => Err(to_read_data_error(err)),
@@ -98,6 +98,7 @@
use libsirenia::rpc::RpcDispatcher;
use libsirenia::storage::Error as StorageError;
use libsirenia::transport::create_transport_from_pipes;
+ use serde_bytes::ByteBuf;
use super::*;
@@ -109,9 +110,9 @@
}
impl TeeApi<Error> for TeeApiServerImpl {
- fn read_data(&mut self, id: String) -> Result<(Status, Vec<u8>)> {
+ fn read_data(&mut self, id: String) -> Result<(Status, ByteBuf)> {
match self.map.borrow().get(&id) {
- Some(val) => Ok((Status::Success, val.to_vec())),
+ Some(val) => Ok((Status::Success, val.clone().into())),
None => Err(anyhow!("id missing")),
}
}
diff --git a/sirenia/src/dugong.rs b/sirenia/src/dugong.rs
index 7071807..d21175c 100644
--- a/sirenia/src/dugong.rs
+++ b/sirenia/src/dugong.rs
@@ -14,6 +14,7 @@
use std::io::Read;
use std::mem::drop;
use std::mem::replace;
+use std::ops::Deref;
use std::ops::DerefMut;
use std::os::unix::net::UnixDatagram;
use std::result::Result as StdResult;
@@ -47,6 +48,7 @@
use libsirenia::transport::DEFAULT_SERVER_PORT;
use log::error;
use log::info;
+use serde_bytes::ByteBuf;
use sirenia::server::register_org_chromium_mana_teeinterface;
use sirenia::server::OrgChromiumManaTEEInterface;
@@ -203,7 +205,7 @@
fn handle_manatee_logs(dugong_state: &DugongState) -> Result<()> {
const LOG_PATH: &str = "/dev/log";
let mut trichechus_client = dugong_state.trichechus_client().lock().unwrap();
- let logs: Vec<Vec<u8>> = trichechus_client
+ let logs: Vec<ByteBuf> = trichechus_client
.get_logs()
.context("failed to call get_logs rpc")?;
if logs.is_empty() {
@@ -214,7 +216,7 @@
let raw_syslog = UnixDatagram::unbound().context("failed connect to /dev/log")?;
for entry in logs.as_slice() {
raw_syslog
- .send_to(entry, LOG_PATH)
+ .send_to(entry.deref(), LOG_PATH)
.context("failed write to /dev/log")?;
}
diff --git a/sirenia/src/trichechus.rs b/sirenia/src/trichechus.rs
index 7778c3f..db7445c 100644
--- a/sirenia/src/trichechus.rs
+++ b/sirenia/src/trichechus.rs
@@ -131,6 +131,7 @@
use log::error;
use log::info;
use log::warn;
+use serde_bytes::ByteBuf;
use sirenia::install_crash_handler;
use sirenia::log_error;
use sirenia::pstore;
@@ -241,9 +242,11 @@
}
impl TeeApi<Error> for TeeAppHandler {
- fn read_data(&mut self, id: String) -> Result<(Status, Vec<u8>)> {
+ fn read_data(&mut self, id: String) -> Result<(Status, ByteBuf)> {
self.conditionally_use_storage_encryption(|params, cronista| {
- cronista.retrieve(params.scope.clone(), params.domain.to_string(), id.clone())
+ cronista
+ .retrieve(params.scope.clone(), params.domain.to_string(), id.clone())
+ .map(|r| (r.0, r.1.into()))
})
}
@@ -487,10 +490,10 @@
Ok(self.state.borrow().app_manifest.clone())
}
- fn get_logs(&mut self) -> Result<Vec<Vec<u8>>> {
+ fn get_logs(&mut self) -> Result<Vec<ByteBuf>> {
let mut replacement: VecDeque<Vec<u8>> = VecDeque::new();
swap(&mut self.state.borrow_mut().log_queue, &mut replacement);
- Ok(replacement.into())
+ Ok(replacement.into_iter().map(Into::<ByteBuf>::into).collect())
}
fn prepare_manatee_memory_service_socket(&mut self, port_number: u32) -> Result<()> {
@@ -532,7 +535,7 @@
None
}
-fn setup_pty(connections: &mut Vec<(Transport, i32)>) -> Result<[Box<dyn Mutator>; 4]> {
+fn setup_pty(connections: &mut [(Transport, i32)]) -> Result<[Box<dyn Mutator>; 4]> {
let (stdin, stdout) =
get_stdio_indices(connections).ok_or_else(|| anyhow!("failed to identify stdio"))?;
let (main, client) = get_a_pty().context("failed get a pty")?;