Loading cmds/servicemanager/ServiceManager.cpp +80 −17 Original line number Diff line number Diff line Loading @@ -249,6 +249,25 @@ static std::vector<std::string> getVintfUpdatableNames(const std::string& apexNa return names; } static std::optional<std::string> getVintfAccessorName(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; std::optional<std::string> accessor; forEachManifest([&](const ManifestWithDescription& mwd) { mwd.manifest->forEachInstance([&](const auto& manifestInstance) { if (manifestInstance.format() != vintf::HalFormat::AIDL) return true; if (manifestInstance.package() != aname.package) return true; if (manifestInstance.interface() != aname.iface) return true; if (manifestInstance.instance() != aname.instance) return true; accessor = manifestInstance.accessor(); return false; // break (libvintf uses opposite convention) }); return false; // continue }); return accessor; } static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; Loading Loading @@ -364,23 +383,40 @@ ServiceManager::~ServiceManager() { } } Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) { Status ServiceManager::getService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); *outBinder = tryGetService(name, true); *outService = tryGetService(name, true); // returns ok regardless of result for legacy reasons return Status::ok(); } Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) { Status ServiceManager::checkService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); *outBinder = tryGetService(name, false); *outService = tryGetService(name, false); // returns ok regardless of result for legacy reasons return Status::ok(); } sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { std::optional<std::string> accessorName; #ifndef VENDORSERVICEMANAGER accessorName = getVintfAccessorName(name); #endif if (accessorName.has_value()) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return os::Service::make<os::Service::Tag::accessor>(nullptr); } return os::Service::make<os::Service::Tag::accessor>( tryGetBinder(*accessorName, startIfNotFound)); } else { return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound)); } } sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); auto ctx = mAccess->getCallingContext(); Loading Loading @@ -565,8 +601,11 @@ Status ServiceManager::registerForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux"); // TODO(b/338541373): Implement the notification mechanism for services accessed via // IAccessor. std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } // note - we could allow isolated apps to get notifications if we Loading Loading @@ -613,8 +652,9 @@ Status ServiceManager::unregisterForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } bool found = false; Loading @@ -638,8 +678,9 @@ Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } *outReturn = false; Loading @@ -662,8 +703,10 @@ binder::Status ServiceManager::getDeclaredInstances(const std::string& interface outReturn->clear(); std::optional<std::string> _accessorName; for (const std::string& instance : allInstances) { if (mAccess->canFind(ctx, interface + "/" + instance)) { if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName); status.isOk()) { outReturn->push_back(instance); } } Loading @@ -681,8 +724,9 @@ Status ServiceManager::updatableViaApex(const std::string& name, auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> _accessorName; if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { return status; } *outReturn = std::nullopt; Loading @@ -706,8 +750,9 @@ Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& ape outReturn->clear(); std::optional<std::string> _accessorName; for (const std::string& name : apexUpdatableNames) { if (mAccess->canFind(ctx, name)) { if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) { outReturn->push_back(name); } } Loading @@ -724,8 +769,9 @@ Status ServiceManager::getConnectionInfo(const std::string& name, auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> _accessorName; if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { return status; } *outReturn = std::nullopt; Loading Loading @@ -1032,6 +1078,23 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::ok(); } Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name, std::optional<std::string>* accessor) { if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service."); } #ifndef VENDORSERVICEMANAGER *accessor = getVintfAccessorName(name); #endif if (accessor->has_value()) { if (!mAccess->canFind(ctx, accessor->value())) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for the accessor of the service."); } } return Status::ok(); } Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) { SM_PERFETTO_TRACE_FUNC(); if (!mAccess->canList(mAccess->getCallingContext())) { Loading cmds/servicemanager/ServiceManager.h +6 −3 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ public: ~ServiceManager(); // getService will try to start any services it cannot find binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status getService(const std::string& name, os::Service* outService) override; binder::Status checkService(const std::string& name, os::Service* outService) override; binder::Status addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) override; binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override; Loading Loading @@ -112,7 +112,10 @@ private: // this updates the iterator to the next location void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it); sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound); os::Service tryGetService(const std::string& name, bool startIfNotFound); sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound); binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name, std::optional<std::string>* accessor); ServiceMap mNameToService; ServiceCallbackMap mNameToRegistrationCallback; Loading cmds/servicemanager/test_sm.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ using android::base::StartsWith; using android::binder::Status; using android::os::BnServiceCallback; using android::os::IServiceManager; using android::os::Service; using testing::_; using testing::ElementsAre; using testing::NiceMock; Loading Loading @@ -153,18 +154,18 @@ TEST(AddService, OverwriteExistingService) { EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> outA; Service outA; EXPECT_TRUE(sm->getService("foo", &outA).isOk()); EXPECT_EQ(serviceA, outA); EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>()); // serviceA should be overwritten by serviceB sp<IBinder> serviceB = getBinder(); EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> outB; Service outB; EXPECT_TRUE(sm->getService("foo", &outB).isOk()); EXPECT_EQ(serviceB, outB); EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>()); } TEST(AddService, NoPermissions) { Loading @@ -186,17 +187,17 @@ TEST(GetService, HappyHappy) { EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(service, out); EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NonExistant) { auto sm = getPermissiveServiceManager(); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, NoPermissionsForGettingService) { Loading @@ -211,10 +212,10 @@ TEST(GetService, NoPermissionsForGettingService) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, AllowedFromIsolated) { Loading @@ -236,9 +237,9 @@ TEST(GetService, AllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(service, out.get()); EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NotAllowedFromIsolated) { Loading @@ -261,10 +262,10 @@ TEST(GetService, NotAllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(ListServices, NoPermissions) { Loading libs/binder/Android.bp +30 −0 Original line number Diff line number Diff line Loading @@ -771,11 +771,41 @@ filegroup { "aidl/android/os/IClientCallback.aidl", "aidl/android/os/IServiceCallback.aidl", "aidl/android/os/IServiceManager.aidl", "aidl/android/os/Service.aidl", "aidl/android/os/ServiceDebugInfo.aidl", ":libbinder_accessor_aidl", ], path: "aidl", } filegroup { name: "libbinder_accessor_aidl", srcs: [ "aidl/android/os/IAccessor.aidl", ], path: "aidl", } // TODO(b/353492849): Make this interface private to libbinder. aidl_interface { name: "android.os.accessor", srcs: [":libbinder_accessor_aidl"], unstable: true, backend: { rust: { enabled: true, apex_available: [ "com.android.virt", ], }, }, visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//packages/modules/Virtualization:__subpackages__", ], } aidl_interface { name: "packagemanager_aidl", unstable: true, Loading libs/binder/BackendUnifiedServiceManager.cpp +52 −4 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ #include "BackendUnifiedServiceManager.h" #include <android/os/IAccessor.h> #include <binder/RpcSession.h> #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) #include <android-base/properties.h> #endif Loading @@ -22,6 +25,7 @@ namespace android { using AidlServiceManager = android::os::IServiceManager; using IAccessor = android::os::IAccessor; BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl) : mTheRealServiceManager(impl) {} Loading @@ -30,13 +34,57 @@ sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() { return mTheRealServiceManager; } binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name, sp<IBinder>* _aidl_return) { return mTheRealServiceManager->getService(name, _aidl_return); os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->getService(name, &service); toBinderService(service, _out); return status; } binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name, sp<IBinder>* _aidl_return) { return mTheRealServiceManager->checkService(name, _aidl_return); os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->checkService(name, &service); toBinderService(service, _out); return status; } void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { switch (in.getTag()) { case os::Service::Tag::binder: { *_out = in; break; } case os::Service::Tag::accessor: { sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder); if (accessor == nullptr) { ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); *_out = os::Service::make<os::Service::Tag::binder>(nullptr); break; } auto request = [=] { os::ParcelFileDescriptor fd; binder::Status ret = accessor->addConnection(&fd); if (ret.isOk()) { return base::unique_fd(fd.release()); } else { ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str()); return base::unique_fd(-1); } }; auto session = RpcSession::make(); session->setupPreconnectedClient(base::unique_fd{}, request); session->setSessionSpecificRoot(accessorBinder); *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); break; } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); } } } binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name, const sp<IBinder>& service, bool allowIsolated, int32_t dumpPriority) { Loading Loading
cmds/servicemanager/ServiceManager.cpp +80 −17 Original line number Diff line number Diff line Loading @@ -249,6 +249,25 @@ static std::vector<std::string> getVintfUpdatableNames(const std::string& apexNa return names; } static std::optional<std::string> getVintfAccessorName(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; std::optional<std::string> accessor; forEachManifest([&](const ManifestWithDescription& mwd) { mwd.manifest->forEachInstance([&](const auto& manifestInstance) { if (manifestInstance.format() != vintf::HalFormat::AIDL) return true; if (manifestInstance.package() != aname.package) return true; if (manifestInstance.interface() != aname.iface) return true; if (manifestInstance.instance() != aname.instance) return true; accessor = manifestInstance.accessor(); return false; // break (libvintf uses opposite convention) }); return false; // continue }); return accessor; } static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; Loading Loading @@ -364,23 +383,40 @@ ServiceManager::~ServiceManager() { } } Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) { Status ServiceManager::getService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); *outBinder = tryGetService(name, true); *outService = tryGetService(name, true); // returns ok regardless of result for legacy reasons return Status::ok(); } Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) { Status ServiceManager::checkService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); *outBinder = tryGetService(name, false); *outService = tryGetService(name, false); // returns ok regardless of result for legacy reasons return Status::ok(); } sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { std::optional<std::string> accessorName; #ifndef VENDORSERVICEMANAGER accessorName = getVintfAccessorName(name); #endif if (accessorName.has_value()) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return os::Service::make<os::Service::Tag::accessor>(nullptr); } return os::Service::make<os::Service::Tag::accessor>( tryGetBinder(*accessorName, startIfNotFound)); } else { return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound)); } } sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); auto ctx = mAccess->getCallingContext(); Loading Loading @@ -565,8 +601,11 @@ Status ServiceManager::registerForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux"); // TODO(b/338541373): Implement the notification mechanism for services accessed via // IAccessor. std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } // note - we could allow isolated apps to get notifications if we Loading Loading @@ -613,8 +652,9 @@ Status ServiceManager::unregisterForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } bool found = false; Loading @@ -638,8 +678,9 @@ Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) { auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> accessorName; if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { return status; } *outReturn = false; Loading @@ -662,8 +703,10 @@ binder::Status ServiceManager::getDeclaredInstances(const std::string& interface outReturn->clear(); std::optional<std::string> _accessorName; for (const std::string& instance : allInstances) { if (mAccess->canFind(ctx, interface + "/" + instance)) { if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName); status.isOk()) { outReturn->push_back(instance); } } Loading @@ -681,8 +724,9 @@ Status ServiceManager::updatableViaApex(const std::string& name, auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> _accessorName; if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { return status; } *outReturn = std::nullopt; Loading @@ -706,8 +750,9 @@ Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& ape outReturn->clear(); std::optional<std::string> _accessorName; for (const std::string& name : apexUpdatableNames) { if (mAccess->canFind(ctx, name)) { if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) { outReturn->push_back(name); } } Loading @@ -724,8 +769,9 @@ Status ServiceManager::getConnectionInfo(const std::string& name, auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); std::optional<std::string> _accessorName; if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { return status; } *outReturn = std::nullopt; Loading Loading @@ -1032,6 +1078,23 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::ok(); } Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name, std::optional<std::string>* accessor) { if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service."); } #ifndef VENDORSERVICEMANAGER *accessor = getVintfAccessorName(name); #endif if (accessor->has_value()) { if (!mAccess->canFind(ctx, accessor->value())) { return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for the accessor of the service."); } } return Status::ok(); } Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) { SM_PERFETTO_TRACE_FUNC(); if (!mAccess->canList(mAccess->getCallingContext())) { Loading
cmds/servicemanager/ServiceManager.h +6 −3 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ public: ~ServiceManager(); // getService will try to start any services it cannot find binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status getService(const std::string& name, os::Service* outService) override; binder::Status checkService(const std::string& name, os::Service* outService) override; binder::Status addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) override; binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override; Loading Loading @@ -112,7 +112,10 @@ private: // this updates the iterator to the next location void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it); sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound); os::Service tryGetService(const std::string& name, bool startIfNotFound); sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound); binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name, std::optional<std::string>* accessor); ServiceMap mNameToService; ServiceCallbackMap mNameToRegistrationCallback; Loading
cmds/servicemanager/test_sm.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ using android::base::StartsWith; using android::binder::Status; using android::os::BnServiceCallback; using android::os::IServiceManager; using android::os::Service; using testing::_; using testing::ElementsAre; using testing::NiceMock; Loading Loading @@ -153,18 +154,18 @@ TEST(AddService, OverwriteExistingService) { EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> outA; Service outA; EXPECT_TRUE(sm->getService("foo", &outA).isOk()); EXPECT_EQ(serviceA, outA); EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>()); // serviceA should be overwritten by serviceB sp<IBinder> serviceB = getBinder(); EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> outB; Service outB; EXPECT_TRUE(sm->getService("foo", &outB).isOk()); EXPECT_EQ(serviceB, outB); EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>()); } TEST(AddService, NoPermissions) { Loading @@ -186,17 +187,17 @@ TEST(GetService, HappyHappy) { EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(service, out); EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NonExistant) { auto sm = getPermissiveServiceManager(); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, NoPermissionsForGettingService) { Loading @@ -211,10 +212,10 @@ TEST(GetService, NoPermissionsForGettingService) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, AllowedFromIsolated) { Loading @@ -236,9 +237,9 @@ TEST(GetService, AllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(service, out.get()); EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NotAllowedFromIsolated) { Loading @@ -261,10 +262,10 @@ TEST(GetService, NotAllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); sp<IBinder> out; Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); EXPECT_EQ(nullptr, out.get()); EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(ListServices, NoPermissions) { Loading
libs/binder/Android.bp +30 −0 Original line number Diff line number Diff line Loading @@ -771,11 +771,41 @@ filegroup { "aidl/android/os/IClientCallback.aidl", "aidl/android/os/IServiceCallback.aidl", "aidl/android/os/IServiceManager.aidl", "aidl/android/os/Service.aidl", "aidl/android/os/ServiceDebugInfo.aidl", ":libbinder_accessor_aidl", ], path: "aidl", } filegroup { name: "libbinder_accessor_aidl", srcs: [ "aidl/android/os/IAccessor.aidl", ], path: "aidl", } // TODO(b/353492849): Make this interface private to libbinder. aidl_interface { name: "android.os.accessor", srcs: [":libbinder_accessor_aidl"], unstable: true, backend: { rust: { enabled: true, apex_available: [ "com.android.virt", ], }, }, visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//packages/modules/Virtualization:__subpackages__", ], } aidl_interface { name: "packagemanager_aidl", unstable: true, Loading
libs/binder/BackendUnifiedServiceManager.cpp +52 −4 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ #include "BackendUnifiedServiceManager.h" #include <android/os/IAccessor.h> #include <binder/RpcSession.h> #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) #include <android-base/properties.h> #endif Loading @@ -22,6 +25,7 @@ namespace android { using AidlServiceManager = android::os::IServiceManager; using IAccessor = android::os::IAccessor; BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl) : mTheRealServiceManager(impl) {} Loading @@ -30,13 +34,57 @@ sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() { return mTheRealServiceManager; } binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name, sp<IBinder>* _aidl_return) { return mTheRealServiceManager->getService(name, _aidl_return); os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->getService(name, &service); toBinderService(service, _out); return status; } binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name, sp<IBinder>* _aidl_return) { return mTheRealServiceManager->checkService(name, _aidl_return); os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->checkService(name, &service); toBinderService(service, _out); return status; } void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { switch (in.getTag()) { case os::Service::Tag::binder: { *_out = in; break; } case os::Service::Tag::accessor: { sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder); if (accessor == nullptr) { ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); *_out = os::Service::make<os::Service::Tag::binder>(nullptr); break; } auto request = [=] { os::ParcelFileDescriptor fd; binder::Status ret = accessor->addConnection(&fd); if (ret.isOk()) { return base::unique_fd(fd.release()); } else { ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str()); return base::unique_fd(-1); } }; auto session = RpcSession::make(); session->setupPreconnectedClient(base::unique_fd{}, request); session->setSessionSpecificRoot(accessorBinder); *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); break; } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); } } } binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name, const sp<IBinder>& service, bool allowIsolated, int32_t dumpPriority) { Loading