Skip to content

Commit 0555fbf

Browse files
Add a method for libbinder to wrap an accessor in a delegator
Libbinder is the only place with the IAccessorDelegator class so it must be responsible for wrapping the IAccesses with an IAccessorDelegator. This is used when the process with the permissions to connect to the server over binder RPC is in a seperate process from the process that wants to serve the IAccessor binder. Test: atest vm_accessor_test binderRpcTest Bug: 358427181 Change-Id: I0839f7d1b466ba9bfb13031596523314718d3677
1 parent 51b2f8f commit 0555fbf

10 files changed

Lines changed: 236 additions & 30 deletions

File tree

libs/binder/Android.bp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ cc_defaults {
489489
"ProcessState.cpp",
490490
"Static.cpp",
491491
":libbinder_aidl",
492+
":libbinder_accessor_aidl",
492493
":libbinder_device_interface_sources",
493494
],
494495
target: {
@@ -801,7 +802,6 @@ filegroup {
801802
"aidl/android/os/IServiceManager.aidl",
802803
"aidl/android/os/Service.aidl",
803804
"aidl/android/os/ServiceDebugInfo.aidl",
804-
":libbinder_accessor_aidl",
805805
],
806806
path: "aidl",
807807
}
@@ -812,26 +812,7 @@ filegroup {
812812
"aidl/android/os/IAccessor.aidl",
813813
],
814814
path: "aidl",
815-
}
816-
817-
// TODO(b/353492849): Make this interface private to libbinder.
818-
aidl_interface {
819-
name: "android.os.accessor",
820-
srcs: [":libbinder_accessor_aidl"],
821-
unstable: true,
822-
backend: {
823-
rust: {
824-
enabled: true,
825-
apex_available: [
826-
"com.android.virt",
827-
],
828-
},
829-
},
830-
visibility: [
831-
":__subpackages__",
832-
"//system/tools/aidl:__subpackages__",
833-
"//packages/modules/Virtualization:__subpackages__",
834-
],
815+
visibility: [":__subpackages__"],
835816
}
836817

837818
aidl_interface {

libs/binder/IServiceManager.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ status_t validateAccessor(const String16& instance, const sp<IBinder>& binder) {
386386
ALOGE("Binder is null");
387387
return BAD_VALUE;
388388
}
389-
sp<IAccessor> accessor = interface_cast<IAccessor>(binder);
389+
sp<IAccessor> accessor = checked_interface_cast<IAccessor>(binder);
390390
if (accessor == nullptr) {
391391
ALOGE("This binder for %s is not an IAccessor binder", String8(instance).c_str());
392392
return BAD_TYPE;
@@ -420,6 +420,28 @@ sp<IBinder> createAccessor(const String16& instance,
420420
return binder;
421421
}
422422

423+
status_t delegateAccessor(const String16& name, const sp<IBinder>& accessor,
424+
sp<IBinder>* delegator) {
425+
LOG_ALWAYS_FATAL_IF(delegator == nullptr, "delegateAccessor called with a null out param");
426+
if (accessor == nullptr) {
427+
ALOGW("Accessor argument to delegateAccessor is null.");
428+
*delegator = nullptr;
429+
return OK;
430+
}
431+
status_t status = validateAccessor(name, accessor);
432+
if (status != OK) {
433+
ALOGE("The provided accessor binder is not an IAccessor for instance %s. Status: "
434+
"%s",
435+
String8(name).c_str(), statusToString(status).c_str());
436+
return status;
437+
}
438+
// validateAccessor already called checked_interface_cast and made sure this
439+
// is a valid accessor object.
440+
*delegator = sp<android::os::IAccessorDelegator>::make(interface_cast<IAccessor>(accessor));
441+
442+
return OK;
443+
}
444+
423445
#if !defined(__ANDROID_VNDK__)
424446
// IPermissionController is not accessible to vendors
425447

libs/binder/include/binder/IServiceManager.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,28 @@ LIBBINDER_EXPORTED sp<IBinder> createAccessor(const String16& instance,
291291
* \return OK if the binder is an IAccessor for `instance`
292292
*/
293293
LIBBINDER_EXPORTED status_t validateAccessor(const String16& instance, const sp<IBinder>& binder);
294+
295+
/**
296+
* Have libbinder wrap this IAccessor binder in an IAccessorDelegator and return
297+
* it.
298+
*
299+
* This is required only in very specific situations when the process that has
300+
* permissions to connect the to RPC service's socket and create the FD for it
301+
* is in a separate process from this process that wants to service the Accessor
302+
* binder and the communication between these two processes is binder RPC. This
303+
* is needed because the binder passed over the binder RPC connection can not be
304+
* used as a kernel binder, and needs to be wrapped by a kernel binder that can
305+
* then be registered with service manager.
306+
*
307+
* \param instance name of the Accessor.
308+
* \param binder to wrap in a Delegator and register with service manager.
309+
* \param outDelegator the wrapped kernel binder for IAccessorDelegator
310+
*
311+
* \return OK if the binder is an IAccessor for `instance` and the delegator was
312+
* successfully created.
313+
*/
314+
LIBBINDER_EXPORTED status_t delegateAccessor(const String16& name, const sp<IBinder>& accessor,
315+
sp<IBinder>* delegator);
294316
#endif // __TRUSTY__
295317

296318
#ifndef __ANDROID__

libs/binder/ndk/binder_rpc.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,28 @@ ABinderRpc_Accessor* ABinderRpc_Accessor_fromBinder(const char* instance, AIBind
302302
}
303303
}
304304

305+
binder_status_t ABinderRpc_Accessor_delegateAccessor(const char* instance, AIBinder* accessor,
306+
AIBinder** outDelegator) {
307+
LOG_ALWAYS_FATAL_IF(outDelegator == nullptr, "The outDelegator argument is null");
308+
if (instance == nullptr || accessor == nullptr) {
309+
ALOGW("instance or accessor arguments to ABinderRpc_Accessor_delegateBinder are null");
310+
*outDelegator = nullptr;
311+
return STATUS_UNEXPECTED_NULL;
312+
}
313+
sp<IBinder> accessorBinder = accessor->getBinder();
314+
315+
sp<IBinder> delegator;
316+
status_t status = android::delegateAccessor(String16(instance), accessorBinder, &delegator);
317+
if (status != OK) {
318+
return PruneStatusT(status);
319+
}
320+
sp<AIBinder> binder = ABpBinder::lookupOrCreateFromBinder(delegator);
321+
// This AIBinder needs a strong ref to pass ownership to the caller
322+
binder->incStrong(nullptr);
323+
*outDelegator = binder.get();
324+
return OK;
325+
}
326+
305327
ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) {
306328
if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) {
307329
ALOGE("Invalid arguments in ABinderRpc_Connection_new");

libs/binder/ndk/include_platform/android/binder_rpc.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,35 @@ ABinderRpc_Accessor* _Nullable ABinderRpc_Accessor_fromBinder(const char* _Nonnu
264264
AIBinder* _Nonnull accessorBinder)
265265
__INTRODUCED_IN(36);
266266

267+
/**
268+
* Wrap an ABinderRpc_Accessor proxy binder with a delegator binder.
269+
*
270+
* The IAccessorDelegator binder delegates all calls to the proxy binder.
271+
*
272+
* This is required only in very specific situations when the process that has
273+
* permissions to connect the to RPC service's socket and create the FD for it
274+
* is in a separate process from this process that wants to serve the Accessor
275+
* binder and the communication between these two processes is binder RPC. This
276+
* is needed because the binder passed over the binder RPC connection can not be
277+
* used as a kernel binder, and needs to be wrapped by a kernel binder that can
278+
* then be registered with service manager.
279+
*
280+
* \param instance name of the service associated with the Accessor
281+
* \param binder the AIBinder* from the ABinderRpc_Accessor from the
282+
* ABinderRpc_Accessor_asBinder. The other process across the binder RPC
283+
* connection will have called this and passed the AIBinder* across a
284+
* binder interface to the process calling this function.
285+
* \param outDelegator the AIBinder* for the kernel binder that wraps the
286+
* 'binder' argument and delegates all calls to it. The caller now owns
287+
* this object with one strong ref count and is responsible for removing
288+
* that ref count with with AIBinder_decStrong when the caller wishes to
289+
* drop the reference.
290+
*/
291+
binder_status_t ABinderRpc_Accessor_delegateAccessor(const char* _Nonnull instance,
292+
AIBinder* _Nonnull binder,
293+
AIBinder* _Nullable* _Nonnull outDelegator)
294+
__INTRODUCED_IN(36);
295+
267296
/**
268297
* Create a new ABinderRpc_ConnectionInfo with sockaddr. This can be supported socket
269298
* types like sockaddr_vm (vsock) and sockaddr_un (Unix Domain Sockets).

libs/binder/ndk/libbinder_ndk.map.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ LIBBINDER_NDK36 { # introduced=36
257257
ABinderRpc_registerAccessorProvider; # systemapi
258258
ABinderRpc_unregisterAccessorProvider; # systemapi
259259
ABinderRpc_Accessor_new; # systemapi
260+
ABinderRpc_Accessor_delegateAccessor; #systemapi
260261
ABinderRpc_Accessor_delete; # systemapi
261262
ABinderRpc_Accessor_asBinder; # systemapi
262263
ABinderRpc_Accessor_fromBinder; # systemapi

libs/binder/rust/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub use service::{
123123
#[cfg(not(trusty))]
124124
pub use state::{ProcessState, ThreadState};
125125
#[cfg(not(any(android_vendor, android_vndk)))]
126-
pub use system_only::{Accessor, ConnectionInfo};
126+
pub use system_only::{delegate_accessor, Accessor, ConnectionInfo};
127127

128128
/// Binder result containing a [`Status`] on error.
129129
pub type Result<T> = std::result::Result<T, Status>;

libs/binder/rust/src/system_only.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
use crate::binder::AsNative;
18+
use crate::error::{status_result, Result};
1719
use crate::proxy::SpIBinder;
1820
use crate::sys;
1921

@@ -185,3 +187,27 @@ impl Drop for Accessor {
185187
}
186188
}
187189
}
190+
191+
/// Register a new service with the default service manager.
192+
///
193+
/// Registers the given binder object with the given identifier. If successful,
194+
/// this service can then be retrieved using that identifier.
195+
///
196+
/// This function will panic if the identifier contains a 0 byte (NUL).
197+
pub fn delegate_accessor(name: &str, mut binder: SpIBinder) -> Result<SpIBinder> {
198+
let instance = CString::new(name).unwrap();
199+
let mut delegator = ptr::null_mut();
200+
let status =
201+
// Safety: `AServiceManager_addService` expects valid `AIBinder` and C
202+
// string pointers. Caller retains ownership of both pointers.
203+
// `AServiceManager_addService` creates a new strong reference and copies
204+
// the string, so both pointers need only be valid until the call returns.
205+
unsafe { sys::ABinderRpc_Accessor_delegateAccessor(instance.as_ptr(),
206+
binder.as_native_mut(), &mut delegator) };
207+
208+
status_result(status)?;
209+
210+
// Safety: `delegator` is either null or a valid, owned pointer at this
211+
// point, so can be safely passed to `SpIBinder::from_raw`.
212+
Ok(unsafe { SpIBinder::from_raw(delegator).expect("Expected valid binder at this point") })
213+
}

libs/binder/rust/tests/integration.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,43 @@ mod tests {
945945
assert!(deleted.load(Ordering::Relaxed));
946946
}
947947

948+
#[test]
949+
fn test_accessor_delegator_new_each_time() {
950+
let get_connection_info = move |_instance: &str| None;
951+
let accessor = Accessor::new("foo.service", get_connection_info);
952+
let delegator_binder =
953+
binder::delegate_accessor("foo.service", accessor.as_binder().unwrap());
954+
let delegator_binder2 =
955+
binder::delegate_accessor("foo.service", accessor.as_binder().unwrap());
956+
957+
// The delegate_accessor creates new delegators each time
958+
assert!(delegator_binder != delegator_binder2);
959+
}
960+
961+
#[test]
962+
fn test_accessor_delegate_the_delegator() {
963+
let get_connection_info = move |_instance: &str| None;
964+
let accessor = Accessor::new("foo.service", get_connection_info);
965+
let delegator_binder =
966+
binder::delegate_accessor("foo.service", accessor.as_binder().unwrap());
967+
let delegator_binder2 =
968+
binder::delegate_accessor("foo.service", delegator_binder.clone().unwrap());
969+
970+
assert!(delegator_binder.clone() == delegator_binder);
971+
// The delegate_accessor creates new delegators each time. Even when they are delegators
972+
// of delegators.
973+
assert!(delegator_binder != delegator_binder2);
974+
}
975+
976+
#[test]
977+
fn test_accessor_delegator_wrong_name() {
978+
let get_connection_info = move |_instance: &str| None;
979+
let accessor = Accessor::new("foo.service", get_connection_info);
980+
let delegator_binder =
981+
binder::delegate_accessor("NOT.foo.service", accessor.as_binder().unwrap());
982+
assert_eq!(delegator_binder, Err(StatusCode::NAME_NOT_FOUND));
983+
}
984+
948985
#[tokio::test]
949986
async fn reassociate_rust_binder_async() {
950987
let service_name = "testing_service";

libs/binder/tests/binderRpcTest.cpp

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ constexpr bool kEnableSharedLibs = true;
7575
constexpr char kTrustyIpcDevice[] = "/dev/trusty-ipc-dev0";
7676
#endif
7777

78+
constexpr char kKnownAidlService[] = "activity";
79+
7880
static std::string WaitStatusToString(int wstatus) {
7981
if (WIFEXITED(wstatus)) {
8082
return "exit status " + std::to_string(WEXITSTATUS(wstatus));
@@ -1549,22 +1551,47 @@ TEST_F(BinderARpcNdk, ARpcNullArgs_ConnectionInfo_new) {
15491551
EXPECT_EQ(nullptr, ABinderRpc_ConnectionInfo_new(reinterpret_cast<const sockaddr*>(&addr), 0));
15501552
}
15511553

1552-
TEST_P(BinderRpcAccessor, ARpcGetService) {
1554+
TEST_F(BinderARpcNdk, ARpcDelegateAccessorWrongInstance) {
1555+
AccessorProviderData* data = new AccessorProviderData();
1556+
ABinderRpc_Accessor* accessor = getAccessor(kARpcInstance, data);
1557+
ASSERT_NE(accessor, nullptr);
1558+
AIBinder* localAccessorBinder = ABinderRpc_Accessor_asBinder(accessor);
1559+
EXPECT_NE(localAccessorBinder, nullptr);
1560+
1561+
AIBinder* delegatorBinder = nullptr;
1562+
binder_status_t status =
1563+
ABinderRpc_Accessor_delegateAccessor("bar", localAccessorBinder, &delegatorBinder);
1564+
EXPECT_EQ(status, NAME_NOT_FOUND);
1565+
1566+
AIBinder_decStrong(localAccessorBinder);
1567+
ABinderRpc_Accessor_delete(accessor);
1568+
delete data;
1569+
}
1570+
1571+
TEST_F(BinderARpcNdk, ARpcDelegateNonAccessor) {
1572+
auto service = defaultServiceManager()->checkService(String16(kKnownAidlService));
1573+
ASSERT_NE(nullptr, service);
1574+
ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(service));
1575+
1576+
AIBinder* delegatorBinder = nullptr;
1577+
binder_status_t status =
1578+
ABinderRpc_Accessor_delegateAccessor("bar", binder.get(), &delegatorBinder);
1579+
1580+
EXPECT_EQ(status, BAD_TYPE);
1581+
}
1582+
1583+
inline void getServiceTest(BinderRpcTestProcessSession& proc,
1584+
ABinderRpc_AccessorProvider_getAccessorCallback getAccessor) {
15531585
constexpr size_t kNumThreads = 10;
15541586
bool isDeleted = false;
15551587

1556-
auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
1557-
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
1558-
15591588
AccessorProviderData* data =
15601589
new AccessorProviderData{proc.proc->sessions[0].addr, proc.proc->sessions[0].addrLen,
15611590
&isDeleted};
1562-
15631591
ABinderRpc_AccessorProvider* provider =
15641592
ABinderRpc_registerAccessorProvider(getAccessor, kARpcSupportedServices,
15651593
kARpcNumSupportedServices, data,
15661594
accessorProviderDataOnDelete);
1567-
15681595
EXPECT_NE(provider, nullptr);
15691596
EXPECT_FALSE(isDeleted);
15701597

@@ -1580,6 +1607,45 @@ TEST_P(BinderRpcAccessor, ARpcGetService) {
15801607
waitForExtraSessionCleanup(proc);
15811608
}
15821609

1610+
TEST_P(BinderRpcAccessor, ARpcGetService) {
1611+
constexpr size_t kNumThreads = 10;
1612+
auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
1613+
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
1614+
1615+
getServiceTest(proc, getAccessor);
1616+
}
1617+
1618+
// Create accessors and wrap each of the accessors in a delegator
1619+
ABinderRpc_Accessor* getDelegatedAccessor(const char* instance, void* cookie) {
1620+
ABinderRpc_Accessor* accessor = getAccessor(instance, cookie);
1621+
AIBinder* accessorBinder = ABinderRpc_Accessor_asBinder(accessor);
1622+
// Once we have a handle to the AIBinder which holds a reference to the
1623+
// underlying accessor IBinder, we can get rid of the ABinderRpc_Accessor
1624+
ABinderRpc_Accessor_delete(accessor);
1625+
1626+
AIBinder* delegatorBinder = nullptr;
1627+
binder_status_t status =
1628+
ABinderRpc_Accessor_delegateAccessor(instance, accessorBinder, &delegatorBinder);
1629+
// No longer need this AIBinder. The delegator has a reference to the
1630+
// underlying IBinder on success, and on failure we are done here.
1631+
AIBinder_decStrong(accessorBinder);
1632+
if (status != OK || delegatorBinder == nullptr) {
1633+
ALOGE("Unexpected behavior. Status: %s, delegator ptr: %p", statusToString(status).c_str(),
1634+
delegatorBinder);
1635+
return nullptr;
1636+
}
1637+
1638+
return ABinderRpc_Accessor_fromBinder(instance, delegatorBinder);
1639+
}
1640+
1641+
TEST_P(BinderRpcAccessor, ARpcGetServiceWithDelegator) {
1642+
constexpr size_t kNumThreads = 10;
1643+
auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
1644+
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
1645+
1646+
getServiceTest(proc, getDelegatedAccessor);
1647+
}
1648+
15831649
#endif // BINDER_WITH_KERNEL_IPC
15841650

15851651
#ifdef BINDER_RPC_TO_TRUSTY_TEST
@@ -1845,7 +1911,7 @@ TEST(BinderRpc, Java) {
18451911
ASSERT_NE(nullptr, sm);
18461912
// Any Java service with non-empty getInterfaceDescriptor() would do.
18471913
// Let's pick activity.
1848-
auto binder = sm->checkService(String16("activity"));
1914+
auto binder = sm->checkService(String16(kKnownAidlService));
18491915
ASSERT_NE(nullptr, binder);
18501916
auto descriptor = binder->getInterfaceDescriptor();
18511917
ASSERT_GE(descriptor.size(), 0u);

0 commit comments

Comments
 (0)