Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88eca4f0 authored by Andrew Walbran's avatar Andrew Walbran
Browse files

Allow set_requesting_sid to be enabled when AIDL Binder is created.

Bug: 181869875
Bug: 178852354
Test: mm
Change-Id: Iff84df4ee4eed2f24d02fd8156b575a443bbb0c6
parent 6fde2dde
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -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))
            }
        }
+5 −6
Original line number Diff line number Diff line
@@ -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.
+41 −22
Original line number Diff line number Diff line
@@ -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 {
        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 {
        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 {
            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 {
        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 {
        let service1 = BnTest::new_binder(
            TestService {
                s: "testing_service1".to_string(),
        });
        let service2 = BnTest::new_binder(TestService {
            },
            BinderFeatures::default(),
        );
        let service2 = BnTest::new_binder(
            TestService {
                s: "testing_service2".to_string(),
        });
            },
            BinderFeatures::default(),
        );

        assert!(!(service1 < service1));
        assert!(!(service1 > service1));
+18 −17
Original line number Diff line number Diff line
@@ -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,7 +35,8 @@ 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) {
    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;
@@ -46,9 +45,11 @@ pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int {
        };

    match service.echo("testing") {
        Ok(s) => if s != "testing" {
        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,
+9 −5
Original line number Diff line number Diff line
@@ -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);