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

Commit c662c5ed authored by Devin Moore's avatar Devin Moore
Browse files

Add rust APIs for new checkServiceAccess method in libbinder

This is used to delegate service checks for another process instead of
the process making the call to servicemanager.

Flag: EXEMPT Clients of this new functionality will be flagged
Test: atest vm_accessor_test
Bug: 358427181
Change-Id: I56926f035c62709ada94d1283079516fa474c58b
parent d19b9a17
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -124,6 +124,11 @@ pub use service::{
    get_declared_instances, is_declared, is_handling_transaction, register_lazy_service,
    wait_for_interface, wait_for_service, LazyServiceGuard,
};
// TODO(b/402766978) Once LLDNK symbols are supported in rust, this can be along with the rest
// of the service symbols in vendor variants.
#[cfg(not(any(trusty, android_ndk, android_vendor, android_vndk)))]
pub use service::check_service_access;

#[cfg(not(any(trusty, android_ndk)))]
#[allow(deprecated)]
pub use service::{get_interface, get_service};
+41 −1
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ use crate::binder::{AsNative, FromIBinder, Strong};
use crate::error::{status_result, Result, StatusCode};
use crate::proxy::SpIBinder;
use crate::sys;

// TODO(b/402766978) Add this back into vendor variants when the LLNDK symbols are supported
// with something like __builtin_available
#[cfg(not(any(trusty, android_ndk, android_vendor, android_vndk)))]
use libc::{pid_t, uid_t};
use std::ffi::{c_void, CStr, CString};
use std::os::raw::c_char;
use std::sync::Mutex;
@@ -246,3 +249,40 @@ pub fn get_declared_instances(interface: &str) -> Result<Vec<String>> {
            StatusCode::BAD_VALUE
        })
}

/// Check if this 'caller_sid' has access for the 'permission' for a given service 'name'.
///
/// This is useful when a process will be making calls to servicemanager on behalf of another
/// process.
/// caller_sid - SELinux context of the process that is being checked.
/// caller_debug_pid - Debug PID of the process that is being checked.
///                    Used for logging denials.
/// callerUid - UID process that is being checked. Used for logging denials
/// name - name of the service that the caller wants to interact with
/// permission - the servicemanager SELinux permission that the process is
///              interested in for the service. This is either "find", "list", or "add".
// TODO(b/402766978) Add this back into vendor variants when the LLNDK symbols are supported
// with something like __builtin_available
#[cfg(not(any(trusty, android_ndk, android_vendor, android_vndk)))]
pub fn check_service_access(
    caller_sid: &str,
    caller_debug_pid: pid_t,
    caller_uid: uid_t,
    name: &str,
    permission: &str,
) -> Result<bool> {
    let caller_sid = CString::new(caller_sid).or(Err(StatusCode::UNEXPECTED_NULL))?;
    let name = CString::new(name).or(Err(StatusCode::UNEXPECTED_NULL))?;
    let permission = CString::new(permission).or(Err(StatusCode::UNEXPECTED_NULL))?;
    // Safety: The CStrings are valid at this point and are only used during the duration
    // of the call.
    unsafe {
        Ok(sys::AServiceManager_checkServiceAccess(
            caller_sid.as_ptr(),
            caller_debug_pid,
            caller_uid,
            name.as_ptr(),
            permission.as_ptr(),
        ))
    }
}