Keystore 2.0: Add error string to service specific exceptions.
This patch adds detailed error messages to the service specific
exceptions. The error messages are formated anyhow::Errors, the same
that already get logged to logcat. Returning them to the client, allows
them to be included in java stack traces which will lead to easier
diagnosis of bugreports.
Test: N/A
Bug: 197890905
Change-Id: Ie6178292650327a1382b04f478ed5fa9e5fd7feb
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index f969cb6..42dd3d2 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -37,6 +37,7 @@
};
use keystore2_selinux as selinux;
use std::cmp::PartialEq;
+use std::ffi::CString;
/// This is the main Keystore error type. It wraps the Keystore `ResponseCode` generated
/// from AIDL in the `Rc` variant and Keymint `ErrorCode` in the Km variant.
@@ -184,6 +185,20 @@
)
}
+/// This function turns an anyhow error into an optional CString.
+/// This is especially useful to add a message string to a service specific error.
+/// If the formatted string was not convertible because it contained a nul byte,
+/// None is returned and a warning is logged.
+pub fn anyhow_error_to_cstring(e: &anyhow::Error) -> Option<CString> {
+ match CString::new(format!("{:?}", e)) {
+ Ok(msg) => Some(msg),
+ Err(_) => {
+ log::warn!("Cannot convert error message to CStr. It contained a nul byte.");
+ None
+ }
+ }
+}
+
/// This function behaves similar to map_or_log_error, but it does not log the errors, instead
/// it calls map_err on the error before mapping it to a binder result allowing callers to
/// log or transform the error before mapping it.
@@ -200,7 +215,10 @@
|e| {
let e = map_err(e);
let rc = get_error_code(&e);
- Err(BinderStatus::new_service_specific_error(rc, None))
+ Err(BinderStatus::new_service_specific_error(
+ rc,
+ anyhow_error_to_cstring(&e).as_deref(),
+ ))
},
handle_ok,
)