Skip to content

Commit 9fe5f80

Browse files
devinmoore-googGerrit Code Review
authored andcommitted
Merge "Add a method for libbinder to wrap an accessor in a delegator" into main
2 parents 4811398 + 0555fbf commit 9fe5f80

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)