diff options
| author | 2021-04-22 15:53:02 +0000 | |
|---|---|---|
| committer | 2021-04-22 15:53:02 +0000 | |
| commit | 2f372a6ec616ca285ee45a716d9524cebde87224 (patch) | |
| tree | 0112ecd1f2dba77b44cd51fe6437c16c67fafe73 | |
| parent | 9399840a3a54588af93856cd0ba7682b8166ea33 (diff) | |
| parent | 88cd995432fb803cb02840694e835d1019302c0f (diff) | |
Merge "Allow set_requesting_sid to be enabled when AIDL Binder is created." am: 10d0432e87 am: 88cd995432
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1674511
Change-Id: I176ed88a4dc847ce2537090fbc5a64167f1cfc95
| -rw-r--r-- | libs/binder/rust/src/binder.rs | 27 | ||||
| -rw-r--r-- | libs/binder/rust/src/lib.rs | 11 | ||||
| -rw-r--r-- | libs/binder/rust/tests/integration.rs | 63 | ||||
| -rw-r--r-- | libs/binder/rust/tests/ndk_rust_interop.rs | 35 | ||||
| -rw-r--r-- | libs/binder/rust/tests/serialization.rs | 14 |
5 files changed, 98 insertions, 52 deletions
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index 321b422185..695a83e414 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -548,6 +548,28 @@ unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> { } } +/// The features to enable when creating a native Binder. +/// +/// This should always be initialised with a default value, e.g.: +/// ``` +/// # use binder::BinderFeatures; +/// BinderFeatures { +/// set_requesting_sid: true, +/// ..BinderFeatures::default(), +/// } +/// ``` +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct BinderFeatures { + /// Indicates that the service intends to receive caller security contexts. This must be true + /// for `ThreadState::with_calling_sid` to work. + pub set_requesting_sid: bool, + // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility + // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct + // expressions entirely. + #[doc(hidden)] + pub _non_exhaustive: (), +} + /// Declare typed interfaces for a binder object. /// /// Given an interface trait and descriptor string, create a native and remote @@ -730,8 +752,9 @@ macro_rules! declare_binder_interface { impl $native { /// Create a new binder service. - pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> { - let binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability); + pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { + let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability); + $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::Strong::new(Box::new(binder)) } } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index 30928a5cff..2694cba870 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -107,10 +107,9 @@ use binder_ndk_sys as sys; pub mod parcel; pub use crate::binder::{ - FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, - Stability, Strong, TransactionCode, TransactionFlags, Weak, - FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, - LAST_CALL_TRANSACTION, + BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, + Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, + FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, }; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::add_service; @@ -125,8 +124,8 @@ pub mod public_api { pub use super::parcel::ParcelFileDescriptor; pub use super::{add_service, get_interface}; pub use super::{ - DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, Status, - StatusCode, Strong, ThreadState, Weak, WpIBinder, + BinderFeatures, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, + Status, StatusCode, Strong, ThreadState, Weak, WpIBinder, }; /// Binder result containing a [`Status`] on error. diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs index 60e3502759..03320076cb 100644 --- a/libs/binder/rust/tests/integration.rs +++ b/libs/binder/rust/tests/integration.rs @@ -19,7 +19,7 @@ use binder::declare_binder_interface; use binder::parcel::Parcel; use binder::{ - Binder, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode, + Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode, FIRST_CALL_TRANSACTION, }; use std::convert::{TryFrom, TryInto}; @@ -55,7 +55,8 @@ fn main() -> Result<(), &'static str> { }))); service.set_requesting_sid(true); if let Some(extension_name) = extension_name { - let extension = BnTest::new_binder(TestService { s: extension_name }); + let extension = + BnTest::new_binder(TestService { s: extension_name }, BinderFeatures::default()); service .set_extension(&mut extension.as_binder()) .expect("Could not add extension"); @@ -212,8 +213,8 @@ mod tests { use std::time::Duration; use binder::{ - Binder, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface, SpIBinder, - StatusCode, Strong, + Binder, BinderFeatures, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface, + SpIBinder, StatusCode, Strong, }; use super::{BnTest, ITest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY}; @@ -495,9 +496,12 @@ mod tests { #[test] fn reassociate_rust_binder() { let service_name = "testing_service"; - let service_ibinder = BnTest::new_binder(TestService { - s: service_name.to_string(), - }) + let service_ibinder = BnTest::new_binder( + TestService { + s: service_name.to_string(), + }, + BinderFeatures::default(), + ) .as_binder(); let service: Strong<dyn ITest> = service_ibinder @@ -510,9 +514,12 @@ mod tests { #[test] fn weak_binder_upgrade() { let service_name = "testing_service"; - let service = BnTest::new_binder(TestService { - s: service_name.to_string(), - }); + let service = BnTest::new_binder( + TestService { + s: service_name.to_string(), + }, + BinderFeatures::default(), + ); let weak = Strong::downgrade(&service); @@ -525,9 +532,12 @@ mod tests { fn weak_binder_upgrade_dead() { let service_name = "testing_service"; let weak = { - let service = BnTest::new_binder(TestService { - s: service_name.to_string(), - }); + let service = BnTest::new_binder( + TestService { + s: service_name.to_string(), + }, + BinderFeatures::default(), + ); Strong::downgrade(&service) }; @@ -538,9 +548,12 @@ mod tests { #[test] fn weak_binder_clone() { let service_name = "testing_service"; - let service = BnTest::new_binder(TestService { - s: service_name.to_string(), - }); + let service = BnTest::new_binder( + TestService { + s: service_name.to_string(), + }, + BinderFeatures::default(), + ); let weak = Strong::downgrade(&service); let cloned = weak.clone(); @@ -556,12 +569,18 @@ mod tests { #[test] #[allow(clippy::eq_op)] fn binder_ord() { - let service1 = BnTest::new_binder(TestService { - s: "testing_service1".to_string(), - }); - let service2 = BnTest::new_binder(TestService { - s: "testing_service2".to_string(), - }); + let service1 = BnTest::new_binder( + TestService { + s: "testing_service1".to_string(), + }, + BinderFeatures::default(), + ); + let service2 = BnTest::new_binder( + TestService { + s: "testing_service2".to_string(), + }, + BinderFeatures::default(), + ); assert!(!(service1 < service1)); assert!(!(service1 > service1)); diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs index ce75ab7125..4702e45f1f 100644 --- a/libs/binder/rust/tests/ndk_rust_interop.rs +++ b/libs/binder/rust/tests/ndk_rust_interop.rs @@ -16,15 +16,13 @@ //! Rust Binder NDK interop tests -use std::ffi::CStr; -use std::os::raw::{c_char, c_int}; -use ::IBinderRustNdkInteropTest::binder::{self, Interface, StatusCode}; use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTest::{ BnBinderRustNdkInteropTest, IBinderRustNdkInteropTest, }; -use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::{ - IBinderRustNdkInteropTestOther, -}; +use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::IBinderRustNdkInteropTestOther; +use ::IBinderRustNdkInteropTest::binder::{self, BinderFeatures, Interface, StatusCode}; +use std::ffi::CStr; +use std::os::raw::{c_char, c_int}; /// Look up the provided AIDL service and call its echo method. /// @@ -37,18 +35,21 @@ pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int { // The Rust class descriptor pointer will not match the NDK one, but the // descriptor strings match so this needs to still associate. - let service: binder::Strong<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) { - Err(e) => { - eprintln!("Could not find Ndk service {}: {:?}", service_name, e); - return StatusCode::NAME_NOT_FOUND as c_int; - } - Ok(service) => service, - }; + let service: binder::Strong<dyn IBinderRustNdkInteropTest> = + match binder::get_interface(service_name) { + Err(e) => { + eprintln!("Could not find Ndk service {}: {:?}", service_name, e); + return StatusCode::NAME_NOT_FOUND as c_int; + } + Ok(service) => service, + }; match service.echo("testing") { - Ok(s) => if s != "testing" { - return StatusCode::BAD_VALUE as c_int; - }, + Ok(s) => { + if s != "testing" { + return StatusCode::BAD_VALUE as c_int; + } + } Err(e) => return e.into(), } @@ -88,7 +89,7 @@ impl IBinderRustNdkInteropTest for Service { #[no_mangle] pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int { let service_name = CStr::from_ptr(service_name).to_str().unwrap(); - let service = BnBinderRustNdkInteropTest::new_binder(Service); + let service = BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default()); match binder::add_service(&service_name, service.as_binder()) { Ok(_) => StatusCode::OK as c_int, Err(e) => e as c_int, diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs index f1b068ee43..66ba846c2d 100644 --- a/libs/binder/rust/tests/serialization.rs +++ b/libs/binder/rust/tests/serialization.rs @@ -18,11 +18,11 @@ //! access. use binder::declare_binder_interface; +use binder::parcel::ParcelFileDescriptor; use binder::{ - Binder, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status, + Binder, BinderFeatures, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status, StatusCode, TransactionCode, }; -use binder::parcel::ParcelFileDescriptor; use std::ffi::{c_void, CStr, CString}; use std::sync::Once; @@ -85,7 +85,7 @@ static mut SERVICE: Option<SpIBinder> = None; pub extern "C" fn rust_service() -> *mut c_void { unsafe { SERVICE_ONCE.call_once(|| { - SERVICE = Some(BnReadParcelTest::new_binder(()).as_binder()); + SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder()); }); SERVICE.as_ref().unwrap().as_raw().cast() } @@ -108,8 +108,12 @@ impl ReadParcelTest for BpReadParcelTest {} impl ReadParcelTest for () {} #[allow(clippy::float_cmp)] -fn on_transact(_service: &dyn ReadParcelTest, code: TransactionCode, - parcel: &Parcel, reply: &mut Parcel) -> Result<()> { +fn on_transact( + _service: &dyn ReadParcelTest, + code: TransactionCode, + parcel: &Parcel, + reply: &mut Parcel, +) -> Result<()> { match code { bindings::Transaction_TEST_BOOL => { assert_eq!(parcel.read::<bool>()?, true); |