Loading cmds/dumpstate/dumpstate.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3538,7 +3538,7 @@ std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() { // the dumpstate's own activity which is irrelevant. RunCommand( SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10).DropRoot().CloseAllFileDescriptorsOnExec().Build(), CommandOptions::WithTimeout(30).DropRoot().CloseAllFileDescriptorsOnExec().Build(), false, outFd); // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip // file in the later stages. Loading libs/binder/IServiceManager.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -157,12 +157,21 @@ protected: class AccessorProvider { public: AccessorProvider(RpcAccessorProvider&& provider) : mProvider(std::move(provider)) {} sp<IBinder> provide(const String16& name) { return mProvider(name); } AccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& provider) : mInstances(std::move(instances)), mProvider(std::move(provider)) {} sp<IBinder> provide(const String16& name) { if (mInstances.count(String8(name).c_str()) > 0) { return mProvider(name); } else { return nullptr; } } const std::set<std::string>& instances() { return mInstances; } private: AccessorProvider() = delete; std::set<std::string> mInstances; RpcAccessorProvider mProvider; }; Loading Loading @@ -318,10 +327,32 @@ sp<IServiceManager> getServiceManagerShimFromAidlServiceManagerForTests( return sp<CppBackendShim>::make(sp<BackendUnifiedServiceManager>::make(sm)); } std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) { // gAccessorProvidersMutex must be locked already static bool isInstanceProvidedLocked(const std::string& instance) { return gAccessorProviders.end() != std::find_if(gAccessorProviders.begin(), gAccessorProviders.end(), [&instance](const AccessorProviderEntry& entry) { return entry.mProvider->instances().count(instance) > 0; }); } std::weak_ptr<AccessorProvider> addAccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& providerCallback) { if (instances.empty()) { ALOGE("Set of instances is empty! Need a non empty set of instances to provide for."); return std::weak_ptr<AccessorProvider>(); } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); for (const auto& instance : instances) { if (isInstanceProvidedLocked(instance)) { ALOGE("The instance %s is already provided for by a previously added " "RpcAccessorProvider.", instance.c_str()); return std::weak_ptr<AccessorProvider>(); } } std::shared_ptr<AccessorProvider> provider = std::make_shared<AccessorProvider>(std::move(providerCallback)); std::make_shared<AccessorProvider>(std::move(instances), std::move(providerCallback)); std::weak_ptr<AccessorProvider> receipt = provider; gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider))); Loading @@ -331,8 +362,9 @@ std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& provid status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) { std::shared_ptr<AccessorProvider> provider = wProvider.lock(); if (provider == nullptr) { ALOGE("The provider supplied to removeAccessorProvider has already been removed."); return NAME_NOT_FOUND; ALOGE("The provider supplied to removeAccessorProvider has already been removed or the " "argument to this function was nullptr."); return BAD_VALUE; } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); size_t sizeBefore = gAccessorProviders.size(); Loading libs/binder/include/binder/IServiceManager.h +20 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <optional> #include <set> namespace android { Loading Loading @@ -224,20 +225,36 @@ LIBBINDER_EXPORTED bool checkPermission(const String16& permission, pid_t pid, u typedef std::function<status_t(const String16& name, sockaddr* outAddr, socklen_t addrSize)> RpcSocketAddressProvider; typedef std::function<sp<IBinder>(const String16& name)> RpcAccessorProvider; /** * This callback provides a way for clients to get access to remote services by * providing an Accessor object from libbinder that can connect to the remote * service over sockets. * * \param instance name of the service that the callback will provide an * Accessor for. The provided accessor will be used to set up a client * RPC connection in libbinder in order to return a binder for the * associated remote service. * * \return IBinder of the Accessor object that libbinder implements. * nullptr if the provider callback doesn't know how to reach the * service or doesn't want to provide access for any other reason. */ typedef std::function<sp<IBinder>(const String16& instance)> RpcAccessorProvider; class AccessorProvider; /** * Register an accessor provider for the service manager APIs. * Register a RpcAccessorProvider for the service manager APIs. * * \param instances that the RpcAccessorProvider knows about and can provide an * Accessor for. * \param provider callback that generates Accessors. * * \return A pointer used as a recept for the successful addition of the * AccessorProvider. This is needed to unregister it later. */ [[nodiscard]] LIBBINDER_EXPORTED std::weak_ptr<AccessorProvider> addAccessorProvider( RpcAccessorProvider&& providerCallback); std::set<std::string>&& instances, RpcAccessorProvider&& providerCallback); /** * Remove an accessor provider using the pointer provided by addAccessorProvider Loading libs/binder/ndk/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ cc_library { "persistable_bundle.cpp", "process.cpp", "service_manager.cpp", "binder_rpc.cpp", ], static_libs: [ Loading libs/binder/ndk/binder_rpc.cpp 0 → 100644 +352 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <android/binder_rpc.h> #include <arpa/inet.h> #include <binder/IServiceManager.h> #include <linux/vm_sockets.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/un.h> #include <variant> #include "ibinder_internal.h" #include "status_internal.h" using ::android::defaultServiceManager; using ::android::IBinder; using ::android::IServiceManager; using ::android::OK; using ::android::sp; using ::android::status_t; using ::android::String16; using ::android::String8; using ::android::binder::Status; #define LOG_ACCESSOR_DEBUG(...) // #define LOG_ACCESSOR_DEBUG(...) ALOGW(__VA_ARGS__) struct ABinderRpc_ConnectionInfo { std::variant<sockaddr_vm, sockaddr_un, sockaddr_in> addr; }; struct ABinderRpc_Accessor final : public ::android::RefBase { static ABinderRpc_Accessor* make(const char* instance, const sp<IBinder>& binder) { LOG_ALWAYS_FATAL_IF(binder == nullptr, "ABinderRpc_Accessor requires a non-null binder"); status_t status = android::validateAccessor(String16(instance), binder); if (status != OK) { ALOGE("The given binder is not a valid IAccessor for %s. Status: %s", instance, android::statusToString(status).c_str()); return nullptr; } return new ABinderRpc_Accessor(binder); } sp<IBinder> asBinder() { return mAccessorBinder; } ~ABinderRpc_Accessor() { LOG_ACCESSOR_DEBUG("ABinderRpc_Accessor dtor"); } private: ABinderRpc_Accessor(sp<IBinder> accessor) : mAccessorBinder(accessor) {} ABinderRpc_Accessor() = delete; sp<IBinder> mAccessorBinder; }; struct ABinderRpc_AccessorProvider { public: static ABinderRpc_AccessorProvider* make(std::weak_ptr<android::AccessorProvider> cookie) { if (cookie.expired()) { ALOGE("Null AccessorProvider cookie from libbinder"); return nullptr; } return new ABinderRpc_AccessorProvider(cookie); } std::weak_ptr<android::AccessorProvider> mProviderCookie; private: ABinderRpc_AccessorProvider() = delete; ABinderRpc_AccessorProvider(std::weak_ptr<android::AccessorProvider> provider) : mProviderCookie(provider) {} }; struct OnDeleteProviderHolder { OnDeleteProviderHolder(void* data, ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) : mData(data), mOnDelete(onDelete) {} ~OnDeleteProviderHolder() { if (mOnDelete) { mOnDelete(mData); } } void* mData; ABinderRpc_AccessorProviderUserData_deleteCallback mOnDelete; // needs to be copyable for std::function, but we will never copy it OnDeleteProviderHolder(const OnDeleteProviderHolder&) { LOG_ALWAYS_FATAL("This object can't be copied!"); } private: OnDeleteProviderHolder() = delete; }; ABinderRpc_AccessorProvider* ABinderRpc_registerAccessorProvider( ABinderRpc_AccessorProvider_getAccessorCallback provider, const char** instances, size_t numInstances, void* data, ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) { if (provider == nullptr) { ALOGE("Null provider passed to ABinderRpc_registerAccessorProvider"); return nullptr; } if (data && onDelete == nullptr) { ALOGE("If a non-null data ptr is passed to ABinderRpc_registerAccessorProvider, then a " "ABinderRpc_AccessorProviderUserData_deleteCallback must alse be passed to delete " "the data object once the ABinderRpc_AccessorProvider is removed."); return nullptr; } if (numInstances == 0 || instances == nullptr) { ALOGE("No instances passed to ABinderRpc_registerAccessorProvider. numInstances: %zu", numInstances); return nullptr; } std::set<std::string> instanceStrings; for (size_t i = 0; i < numInstances; i++) { instanceStrings.emplace(instances[i]); } // call the onDelete when the last reference of this goes away (when the // last reference to the generate std::function goes away). std::shared_ptr<OnDeleteProviderHolder> onDeleteHolder = std::make_shared<OnDeleteProviderHolder>(data, onDelete); android::RpcAccessorProvider generate = [provider, onDeleteHolder](const String16& name) -> sp<IBinder> { ABinderRpc_Accessor* accessor = provider(String8(name).c_str(), onDeleteHolder->mData); if (accessor == nullptr) { ALOGE("The supplied ABinderRpc_AccessorProvider_getAccessorCallback returned nullptr"); return nullptr; } sp<IBinder> binder = accessor->asBinder(); ABinderRpc_Accessor_delete(accessor); return binder; }; std::weak_ptr<android::AccessorProvider> cookie = android::addAccessorProvider(std::move(instanceStrings), std::move(generate)); return ABinderRpc_AccessorProvider::make(cookie); } void ABinderRpc_unregisterAccessorProvider(ABinderRpc_AccessorProvider* provider) { if (provider == nullptr) { LOG_ALWAYS_FATAL("Attempting to remove a null ABinderRpc_AccessorProvider"); } status_t status = android::removeAccessorProvider(provider->mProviderCookie); // There shouldn't be a way to get here because the caller won't have a // ABinderRpc_AccessorProvider* without calling ABinderRpc_registerAccessorProvider LOG_ALWAYS_FATAL_IF(status == android::BAD_VALUE, "Provider (%p) is not valid. Status: %s", provider, android::statusToString(status).c_str()); LOG_ALWAYS_FATAL_IF(status == android::NAME_NOT_FOUND, "Provider (%p) was already unregistered. Status: %s", provider, android::statusToString(status).c_str()); LOG_ALWAYS_FATAL_IF(status != OK, "Unknown error when attempting to unregister ABinderRpc_AccessorProvider " "(%p). Status: %s", provider, android::statusToString(status).c_str()); delete provider; } struct OnDeleteConnectionInfoHolder { OnDeleteConnectionInfoHolder(void* data, ABinderRpc_ConnectionInfoProviderUserData_delete onDelete) : mData(data), mOnDelete(onDelete) {} ~OnDeleteConnectionInfoHolder() { if (mOnDelete) { mOnDelete(mData); } } void* mData; ABinderRpc_ConnectionInfoProviderUserData_delete mOnDelete; // needs to be copyable for std::function, but we will never copy it OnDeleteConnectionInfoHolder(const OnDeleteConnectionInfoHolder&) { LOG_ALWAYS_FATAL("This object can't be copied!"); } private: OnDeleteConnectionInfoHolder() = delete; }; ABinderRpc_Accessor* ABinderRpc_Accessor_new( const char* instance, ABinderRpc_ConnectionInfoProvider provider, void* data, ABinderRpc_ConnectionInfoProviderUserData_delete onDelete) { if (instance == nullptr) { ALOGE("Instance argument must be valid when calling ABinderRpc_Accessor_new"); return nullptr; } if (data && onDelete == nullptr) { ALOGE("If a non-null data ptr is passed to ABinderRpc_Accessor_new, then a " "ABinderRpc_ConnectionInfoProviderUserData_delete callback must alse be passed to " "delete " "the data object once the ABinderRpc_Accessor is deleted."); return nullptr; } std::shared_ptr<OnDeleteConnectionInfoHolder> onDeleteHolder = std::make_shared<OnDeleteConnectionInfoHolder>(data, onDelete); if (provider == nullptr) { ALOGE("Can't create a new ABinderRpc_Accessor without a ABinderRpc_ConnectionInfoProvider " "and it is " "null"); return nullptr; } android::RpcSocketAddressProvider generate = [provider, onDeleteHolder]( const String16& name, sockaddr* outAddr, size_t addrLen) -> status_t { std::unique_ptr<ABinderRpc_ConnectionInfo> info( provider(String8(name).c_str(), onDeleteHolder->mData)); if (info == nullptr) { ALOGE("The supplied ABinderRpc_ConnectionInfoProvider returned nullptr"); return android::NAME_NOT_FOUND; } if (auto addr = std::get_if<sockaddr_vm>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->svm_family != AF_VSOCK, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_vm)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_vm), addrLen); return android::BAD_VALUE; } LOG_ACCESSOR_DEBUG( "Connection info provider found AF_VSOCK. family %d, port %d, cid %d", addr->svm_family, addr->svm_port, addr->svm_cid); *reinterpret_cast<sockaddr_vm*>(outAddr) = *addr; } else if (auto addr = std::get_if<sockaddr_un>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->sun_family != AF_UNIX, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_un)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_un), addrLen); return android::BAD_VALUE; } *reinterpret_cast<sockaddr_un*>(outAddr) = *addr; } else if (auto addr = std::get_if<sockaddr_in>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->sin_family != AF_INET, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_in)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_in), addrLen); return android::BAD_VALUE; } *reinterpret_cast<sockaddr_in*>(outAddr) = *addr; } else { LOG_ALWAYS_FATAL( "Unsupported address family type when trying to get ARpcConnection info. A " "new variant was added to the ABinderRpc_ConnectionInfo and this needs to be " "updated."); } return OK; }; sp<IBinder> accessorBinder = android::createAccessor(String16(instance), std::move(generate)); if (accessorBinder == nullptr) { ALOGE("service manager did not get us an accessor"); return nullptr; } LOG_ACCESSOR_DEBUG("service manager found an accessor, so returning one now from _new"); return ABinderRpc_Accessor::make(instance, accessorBinder); } void ABinderRpc_Accessor_delete(ABinderRpc_Accessor* accessor) { delete accessor; } AIBinder* ABinderRpc_Accessor_asBinder(ABinderRpc_Accessor* accessor) { if (!accessor) { ALOGE("ABinderRpc_Accessor argument is null."); return nullptr; } sp<IBinder> binder = accessor->asBinder(); sp<AIBinder> aBinder = ABpBinder::lookupOrCreateFromBinder(binder); AIBinder* ptr = aBinder.get(); if (ptr == nullptr) { LOG_ALWAYS_FATAL("Failed to lookupOrCreateFromBinder"); } ptr->incStrong(nullptr); return ptr; } ABinderRpc_Accessor* ABinderRpc_Accessor_fromBinder(const char* instance, AIBinder* binder) { if (!binder) { ALOGE("binder argument is null"); return nullptr; } sp<IBinder> accessorBinder = binder->getBinder(); if (accessorBinder) { return ABinderRpc_Accessor::make(instance, accessorBinder); } else { ALOGE("Attempting to get an ABinderRpc_Accessor for %s but AIBinder::getBinder returned " "null", instance); return nullptr; } } ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) { if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) { ALOGE("Invalid arguments in Arpc_Connection_new"); return nullptr; } // socklen_t was int32_t on 32-bit and uint32_t on 64 bit. size_t socklen = len < 0 || static_cast<uintmax_t>(len) > SIZE_MAX ? 0 : len; if (addr->sa_family == AF_VSOCK) { if (len != sizeof(sockaddr_vm)) { ALOGE("Incorrect size of %zu for AF_VSOCK sockaddr_vm. Expecting %zu", socklen, sizeof(sockaddr_vm)); return nullptr; } sockaddr_vm vm = *reinterpret_cast<const sockaddr_vm*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_VSOCK. family %d, port %d, cid %d", vm.svm_family, vm.svm_port, vm.svm_cid); return new ABinderRpc_ConnectionInfo(vm); } else if (addr->sa_family == AF_UNIX) { if (len != sizeof(sockaddr_un)) { ALOGE("Incorrect size of %zu for AF_UNIX sockaddr_un. Expecting %zu", socklen, sizeof(sockaddr_un)); return nullptr; } sockaddr_un un = *reinterpret_cast<const sockaddr_un*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_UNIX. family %d, path %s", un.sun_family, un.sun_path); return new ABinderRpc_ConnectionInfo(un); } else if (addr->sa_family == AF_INET) { if (len != sizeof(sockaddr_in)) { ALOGE("Incorrect size of %zu for AF_INET sockaddr_in. Expecting %zu", socklen, sizeof(sockaddr_in)); return nullptr; } sockaddr_in in = *reinterpret_cast<const sockaddr_in*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_INET. family %d, address %s, port %d", in.sin_family, inet_ntoa(in.sin_addr), ntohs(in.sin_port)); return new ABinderRpc_ConnectionInfo(in); } ALOGE("ARpc APIs only support AF_VSOCK right now but the supplied sockadder::sa_family is: %hu", addr->sa_family); return nullptr; } void ABinderRpc_ConnectionInfo_delete(ABinderRpc_ConnectionInfo* info) { delete info; } Loading
cmds/dumpstate/dumpstate.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3538,7 +3538,7 @@ std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() { // the dumpstate's own activity which is irrelevant. RunCommand( SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10).DropRoot().CloseAllFileDescriptorsOnExec().Build(), CommandOptions::WithTimeout(30).DropRoot().CloseAllFileDescriptorsOnExec().Build(), false, outFd); // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip // file in the later stages. Loading
libs/binder/IServiceManager.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -157,12 +157,21 @@ protected: class AccessorProvider { public: AccessorProvider(RpcAccessorProvider&& provider) : mProvider(std::move(provider)) {} sp<IBinder> provide(const String16& name) { return mProvider(name); } AccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& provider) : mInstances(std::move(instances)), mProvider(std::move(provider)) {} sp<IBinder> provide(const String16& name) { if (mInstances.count(String8(name).c_str()) > 0) { return mProvider(name); } else { return nullptr; } } const std::set<std::string>& instances() { return mInstances; } private: AccessorProvider() = delete; std::set<std::string> mInstances; RpcAccessorProvider mProvider; }; Loading Loading @@ -318,10 +327,32 @@ sp<IServiceManager> getServiceManagerShimFromAidlServiceManagerForTests( return sp<CppBackendShim>::make(sp<BackendUnifiedServiceManager>::make(sm)); } std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) { // gAccessorProvidersMutex must be locked already static bool isInstanceProvidedLocked(const std::string& instance) { return gAccessorProviders.end() != std::find_if(gAccessorProviders.begin(), gAccessorProviders.end(), [&instance](const AccessorProviderEntry& entry) { return entry.mProvider->instances().count(instance) > 0; }); } std::weak_ptr<AccessorProvider> addAccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& providerCallback) { if (instances.empty()) { ALOGE("Set of instances is empty! Need a non empty set of instances to provide for."); return std::weak_ptr<AccessorProvider>(); } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); for (const auto& instance : instances) { if (isInstanceProvidedLocked(instance)) { ALOGE("The instance %s is already provided for by a previously added " "RpcAccessorProvider.", instance.c_str()); return std::weak_ptr<AccessorProvider>(); } } std::shared_ptr<AccessorProvider> provider = std::make_shared<AccessorProvider>(std::move(providerCallback)); std::make_shared<AccessorProvider>(std::move(instances), std::move(providerCallback)); std::weak_ptr<AccessorProvider> receipt = provider; gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider))); Loading @@ -331,8 +362,9 @@ std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& provid status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) { std::shared_ptr<AccessorProvider> provider = wProvider.lock(); if (provider == nullptr) { ALOGE("The provider supplied to removeAccessorProvider has already been removed."); return NAME_NOT_FOUND; ALOGE("The provider supplied to removeAccessorProvider has already been removed or the " "argument to this function was nullptr."); return BAD_VALUE; } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); size_t sizeBefore = gAccessorProviders.size(); Loading
libs/binder/include/binder/IServiceManager.h +20 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <optional> #include <set> namespace android { Loading Loading @@ -224,20 +225,36 @@ LIBBINDER_EXPORTED bool checkPermission(const String16& permission, pid_t pid, u typedef std::function<status_t(const String16& name, sockaddr* outAddr, socklen_t addrSize)> RpcSocketAddressProvider; typedef std::function<sp<IBinder>(const String16& name)> RpcAccessorProvider; /** * This callback provides a way for clients to get access to remote services by * providing an Accessor object from libbinder that can connect to the remote * service over sockets. * * \param instance name of the service that the callback will provide an * Accessor for. The provided accessor will be used to set up a client * RPC connection in libbinder in order to return a binder for the * associated remote service. * * \return IBinder of the Accessor object that libbinder implements. * nullptr if the provider callback doesn't know how to reach the * service or doesn't want to provide access for any other reason. */ typedef std::function<sp<IBinder>(const String16& instance)> RpcAccessorProvider; class AccessorProvider; /** * Register an accessor provider for the service manager APIs. * Register a RpcAccessorProvider for the service manager APIs. * * \param instances that the RpcAccessorProvider knows about and can provide an * Accessor for. * \param provider callback that generates Accessors. * * \return A pointer used as a recept for the successful addition of the * AccessorProvider. This is needed to unregister it later. */ [[nodiscard]] LIBBINDER_EXPORTED std::weak_ptr<AccessorProvider> addAccessorProvider( RpcAccessorProvider&& providerCallback); std::set<std::string>&& instances, RpcAccessorProvider&& providerCallback); /** * Remove an accessor provider using the pointer provided by addAccessorProvider Loading
libs/binder/ndk/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ cc_library { "persistable_bundle.cpp", "process.cpp", "service_manager.cpp", "binder_rpc.cpp", ], static_libs: [ Loading
libs/binder/ndk/binder_rpc.cpp 0 → 100644 +352 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <android/binder_rpc.h> #include <arpa/inet.h> #include <binder/IServiceManager.h> #include <linux/vm_sockets.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/un.h> #include <variant> #include "ibinder_internal.h" #include "status_internal.h" using ::android::defaultServiceManager; using ::android::IBinder; using ::android::IServiceManager; using ::android::OK; using ::android::sp; using ::android::status_t; using ::android::String16; using ::android::String8; using ::android::binder::Status; #define LOG_ACCESSOR_DEBUG(...) // #define LOG_ACCESSOR_DEBUG(...) ALOGW(__VA_ARGS__) struct ABinderRpc_ConnectionInfo { std::variant<sockaddr_vm, sockaddr_un, sockaddr_in> addr; }; struct ABinderRpc_Accessor final : public ::android::RefBase { static ABinderRpc_Accessor* make(const char* instance, const sp<IBinder>& binder) { LOG_ALWAYS_FATAL_IF(binder == nullptr, "ABinderRpc_Accessor requires a non-null binder"); status_t status = android::validateAccessor(String16(instance), binder); if (status != OK) { ALOGE("The given binder is not a valid IAccessor for %s. Status: %s", instance, android::statusToString(status).c_str()); return nullptr; } return new ABinderRpc_Accessor(binder); } sp<IBinder> asBinder() { return mAccessorBinder; } ~ABinderRpc_Accessor() { LOG_ACCESSOR_DEBUG("ABinderRpc_Accessor dtor"); } private: ABinderRpc_Accessor(sp<IBinder> accessor) : mAccessorBinder(accessor) {} ABinderRpc_Accessor() = delete; sp<IBinder> mAccessorBinder; }; struct ABinderRpc_AccessorProvider { public: static ABinderRpc_AccessorProvider* make(std::weak_ptr<android::AccessorProvider> cookie) { if (cookie.expired()) { ALOGE("Null AccessorProvider cookie from libbinder"); return nullptr; } return new ABinderRpc_AccessorProvider(cookie); } std::weak_ptr<android::AccessorProvider> mProviderCookie; private: ABinderRpc_AccessorProvider() = delete; ABinderRpc_AccessorProvider(std::weak_ptr<android::AccessorProvider> provider) : mProviderCookie(provider) {} }; struct OnDeleteProviderHolder { OnDeleteProviderHolder(void* data, ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) : mData(data), mOnDelete(onDelete) {} ~OnDeleteProviderHolder() { if (mOnDelete) { mOnDelete(mData); } } void* mData; ABinderRpc_AccessorProviderUserData_deleteCallback mOnDelete; // needs to be copyable for std::function, but we will never copy it OnDeleteProviderHolder(const OnDeleteProviderHolder&) { LOG_ALWAYS_FATAL("This object can't be copied!"); } private: OnDeleteProviderHolder() = delete; }; ABinderRpc_AccessorProvider* ABinderRpc_registerAccessorProvider( ABinderRpc_AccessorProvider_getAccessorCallback provider, const char** instances, size_t numInstances, void* data, ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) { if (provider == nullptr) { ALOGE("Null provider passed to ABinderRpc_registerAccessorProvider"); return nullptr; } if (data && onDelete == nullptr) { ALOGE("If a non-null data ptr is passed to ABinderRpc_registerAccessorProvider, then a " "ABinderRpc_AccessorProviderUserData_deleteCallback must alse be passed to delete " "the data object once the ABinderRpc_AccessorProvider is removed."); return nullptr; } if (numInstances == 0 || instances == nullptr) { ALOGE("No instances passed to ABinderRpc_registerAccessorProvider. numInstances: %zu", numInstances); return nullptr; } std::set<std::string> instanceStrings; for (size_t i = 0; i < numInstances; i++) { instanceStrings.emplace(instances[i]); } // call the onDelete when the last reference of this goes away (when the // last reference to the generate std::function goes away). std::shared_ptr<OnDeleteProviderHolder> onDeleteHolder = std::make_shared<OnDeleteProviderHolder>(data, onDelete); android::RpcAccessorProvider generate = [provider, onDeleteHolder](const String16& name) -> sp<IBinder> { ABinderRpc_Accessor* accessor = provider(String8(name).c_str(), onDeleteHolder->mData); if (accessor == nullptr) { ALOGE("The supplied ABinderRpc_AccessorProvider_getAccessorCallback returned nullptr"); return nullptr; } sp<IBinder> binder = accessor->asBinder(); ABinderRpc_Accessor_delete(accessor); return binder; }; std::weak_ptr<android::AccessorProvider> cookie = android::addAccessorProvider(std::move(instanceStrings), std::move(generate)); return ABinderRpc_AccessorProvider::make(cookie); } void ABinderRpc_unregisterAccessorProvider(ABinderRpc_AccessorProvider* provider) { if (provider == nullptr) { LOG_ALWAYS_FATAL("Attempting to remove a null ABinderRpc_AccessorProvider"); } status_t status = android::removeAccessorProvider(provider->mProviderCookie); // There shouldn't be a way to get here because the caller won't have a // ABinderRpc_AccessorProvider* without calling ABinderRpc_registerAccessorProvider LOG_ALWAYS_FATAL_IF(status == android::BAD_VALUE, "Provider (%p) is not valid. Status: %s", provider, android::statusToString(status).c_str()); LOG_ALWAYS_FATAL_IF(status == android::NAME_NOT_FOUND, "Provider (%p) was already unregistered. Status: %s", provider, android::statusToString(status).c_str()); LOG_ALWAYS_FATAL_IF(status != OK, "Unknown error when attempting to unregister ABinderRpc_AccessorProvider " "(%p). Status: %s", provider, android::statusToString(status).c_str()); delete provider; } struct OnDeleteConnectionInfoHolder { OnDeleteConnectionInfoHolder(void* data, ABinderRpc_ConnectionInfoProviderUserData_delete onDelete) : mData(data), mOnDelete(onDelete) {} ~OnDeleteConnectionInfoHolder() { if (mOnDelete) { mOnDelete(mData); } } void* mData; ABinderRpc_ConnectionInfoProviderUserData_delete mOnDelete; // needs to be copyable for std::function, but we will never copy it OnDeleteConnectionInfoHolder(const OnDeleteConnectionInfoHolder&) { LOG_ALWAYS_FATAL("This object can't be copied!"); } private: OnDeleteConnectionInfoHolder() = delete; }; ABinderRpc_Accessor* ABinderRpc_Accessor_new( const char* instance, ABinderRpc_ConnectionInfoProvider provider, void* data, ABinderRpc_ConnectionInfoProviderUserData_delete onDelete) { if (instance == nullptr) { ALOGE("Instance argument must be valid when calling ABinderRpc_Accessor_new"); return nullptr; } if (data && onDelete == nullptr) { ALOGE("If a non-null data ptr is passed to ABinderRpc_Accessor_new, then a " "ABinderRpc_ConnectionInfoProviderUserData_delete callback must alse be passed to " "delete " "the data object once the ABinderRpc_Accessor is deleted."); return nullptr; } std::shared_ptr<OnDeleteConnectionInfoHolder> onDeleteHolder = std::make_shared<OnDeleteConnectionInfoHolder>(data, onDelete); if (provider == nullptr) { ALOGE("Can't create a new ABinderRpc_Accessor without a ABinderRpc_ConnectionInfoProvider " "and it is " "null"); return nullptr; } android::RpcSocketAddressProvider generate = [provider, onDeleteHolder]( const String16& name, sockaddr* outAddr, size_t addrLen) -> status_t { std::unique_ptr<ABinderRpc_ConnectionInfo> info( provider(String8(name).c_str(), onDeleteHolder->mData)); if (info == nullptr) { ALOGE("The supplied ABinderRpc_ConnectionInfoProvider returned nullptr"); return android::NAME_NOT_FOUND; } if (auto addr = std::get_if<sockaddr_vm>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->svm_family != AF_VSOCK, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_vm)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_vm), addrLen); return android::BAD_VALUE; } LOG_ACCESSOR_DEBUG( "Connection info provider found AF_VSOCK. family %d, port %d, cid %d", addr->svm_family, addr->svm_port, addr->svm_cid); *reinterpret_cast<sockaddr_vm*>(outAddr) = *addr; } else if (auto addr = std::get_if<sockaddr_un>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->sun_family != AF_UNIX, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_un)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_un), addrLen); return android::BAD_VALUE; } *reinterpret_cast<sockaddr_un*>(outAddr) = *addr; } else if (auto addr = std::get_if<sockaddr_in>(&info->addr)) { LOG_ALWAYS_FATAL_IF(addr->sin_family != AF_INET, "ABinderRpc_ConnectionInfo invalid family"); if (addrLen < sizeof(sockaddr_in)) { ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_in), addrLen); return android::BAD_VALUE; } *reinterpret_cast<sockaddr_in*>(outAddr) = *addr; } else { LOG_ALWAYS_FATAL( "Unsupported address family type when trying to get ARpcConnection info. A " "new variant was added to the ABinderRpc_ConnectionInfo and this needs to be " "updated."); } return OK; }; sp<IBinder> accessorBinder = android::createAccessor(String16(instance), std::move(generate)); if (accessorBinder == nullptr) { ALOGE("service manager did not get us an accessor"); return nullptr; } LOG_ACCESSOR_DEBUG("service manager found an accessor, so returning one now from _new"); return ABinderRpc_Accessor::make(instance, accessorBinder); } void ABinderRpc_Accessor_delete(ABinderRpc_Accessor* accessor) { delete accessor; } AIBinder* ABinderRpc_Accessor_asBinder(ABinderRpc_Accessor* accessor) { if (!accessor) { ALOGE("ABinderRpc_Accessor argument is null."); return nullptr; } sp<IBinder> binder = accessor->asBinder(); sp<AIBinder> aBinder = ABpBinder::lookupOrCreateFromBinder(binder); AIBinder* ptr = aBinder.get(); if (ptr == nullptr) { LOG_ALWAYS_FATAL("Failed to lookupOrCreateFromBinder"); } ptr->incStrong(nullptr); return ptr; } ABinderRpc_Accessor* ABinderRpc_Accessor_fromBinder(const char* instance, AIBinder* binder) { if (!binder) { ALOGE("binder argument is null"); return nullptr; } sp<IBinder> accessorBinder = binder->getBinder(); if (accessorBinder) { return ABinderRpc_Accessor::make(instance, accessorBinder); } else { ALOGE("Attempting to get an ABinderRpc_Accessor for %s but AIBinder::getBinder returned " "null", instance); return nullptr; } } ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) { if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) { ALOGE("Invalid arguments in Arpc_Connection_new"); return nullptr; } // socklen_t was int32_t on 32-bit and uint32_t on 64 bit. size_t socklen = len < 0 || static_cast<uintmax_t>(len) > SIZE_MAX ? 0 : len; if (addr->sa_family == AF_VSOCK) { if (len != sizeof(sockaddr_vm)) { ALOGE("Incorrect size of %zu for AF_VSOCK sockaddr_vm. Expecting %zu", socklen, sizeof(sockaddr_vm)); return nullptr; } sockaddr_vm vm = *reinterpret_cast<const sockaddr_vm*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_VSOCK. family %d, port %d, cid %d", vm.svm_family, vm.svm_port, vm.svm_cid); return new ABinderRpc_ConnectionInfo(vm); } else if (addr->sa_family == AF_UNIX) { if (len != sizeof(sockaddr_un)) { ALOGE("Incorrect size of %zu for AF_UNIX sockaddr_un. Expecting %zu", socklen, sizeof(sockaddr_un)); return nullptr; } sockaddr_un un = *reinterpret_cast<const sockaddr_un*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_UNIX. family %d, path %s", un.sun_family, un.sun_path); return new ABinderRpc_ConnectionInfo(un); } else if (addr->sa_family == AF_INET) { if (len != sizeof(sockaddr_in)) { ALOGE("Incorrect size of %zu for AF_INET sockaddr_in. Expecting %zu", socklen, sizeof(sockaddr_in)); return nullptr; } sockaddr_in in = *reinterpret_cast<const sockaddr_in*>(addr); LOG_ACCESSOR_DEBUG("Arpc_ConnectionInfo_new found AF_INET. family %d, address %s, port %d", in.sin_family, inet_ntoa(in.sin_addr), ntohs(in.sin_port)); return new ABinderRpc_ConnectionInfo(in); } ALOGE("ARpc APIs only support AF_VSOCK right now but the supplied sockadder::sa_family is: %hu", addr->sa_family); return nullptr; } void ABinderRpc_ConnectionInfo_delete(ABinderRpc_ConnectionInfo* info) { delete info; }