Loading cmds/servicemanager/ServiceManager.cpp +18 −8 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ using ::android::internal::Stability; namespace android { bool is_multiuser_uid_isolated(uid_t uid) { uid_t appid = multiuser_get_app_id(uid); return appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END; } #ifndef VENDORSERVICEMANAGER struct ManifestWithDescription { Loading Loading @@ -273,14 +278,9 @@ sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfN if (auto it = mNameToService.find(name); it != mNameToService.end()) { service = &(it->second); if (!service->allowIsolated) { uid_t appid = multiuser_get_app_id(ctx.uid); bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END; if (isIsolated) { if (!service->allowIsolated && is_multiuser_uid_isolated(ctx.uid)) { return nullptr; } } out = service->binder; } Loading Loading @@ -425,7 +425,17 @@ Status ServiceManager::registerForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY); return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux"); } // note - we could allow isolated apps to get notifications if we // keep track of isolated callbacks and non-isolated callbacks, but // this is done since isolated apps shouldn't access lazy services // so we should be able to use different APIs to keep things simple. // Here, we disallow everything, because the service might not be // registered yet. if (is_multiuser_uid_isolated(ctx.uid)) { return Status::fromExceptionCode(Status::EX_SECURITY, "isolated app"); } if (!isValidServiceName(name)) { Loading cmds/servicemanager/test_sm.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,22 @@ TEST(ServiceNotifications, NoPermissionsRegister) { sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(), Status::EX_SECURITY); } TEST(GetService, IsolatedCantRegister) { std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); EXPECT_CALL(*access, getCallingContext()) .WillOnce(Return(Access::CallingContext{ .uid = AID_ISOLATED_START, })); EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access)); sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(), Status::EX_SECURITY); } Loading Loading
cmds/servicemanager/ServiceManager.cpp +18 −8 Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ using ::android::internal::Stability; namespace android { bool is_multiuser_uid_isolated(uid_t uid) { uid_t appid = multiuser_get_app_id(uid); return appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END; } #ifndef VENDORSERVICEMANAGER struct ManifestWithDescription { Loading Loading @@ -273,14 +278,9 @@ sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfN if (auto it = mNameToService.find(name); it != mNameToService.end()) { service = &(it->second); if (!service->allowIsolated) { uid_t appid = multiuser_get_app_id(ctx.uid); bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END; if (isIsolated) { if (!service->allowIsolated && is_multiuser_uid_isolated(ctx.uid)) { return nullptr; } } out = service->binder; } Loading Loading @@ -425,7 +425,17 @@ Status ServiceManager::registerForNotifications( auto ctx = mAccess->getCallingContext(); if (!mAccess->canFind(ctx, name)) { return Status::fromExceptionCode(Status::EX_SECURITY); return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux"); } // note - we could allow isolated apps to get notifications if we // keep track of isolated callbacks and non-isolated callbacks, but // this is done since isolated apps shouldn't access lazy services // so we should be able to use different APIs to keep things simple. // Here, we disallow everything, because the service might not be // registered yet. if (is_multiuser_uid_isolated(ctx.uid)) { return Status::fromExceptionCode(Status::EX_SECURITY, "isolated app"); } if (!isValidServiceName(name)) { Loading
cmds/servicemanager/test_sm.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,22 @@ TEST(ServiceNotifications, NoPermissionsRegister) { sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(), Status::EX_SECURITY); } TEST(GetService, IsolatedCantRegister) { std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); EXPECT_CALL(*access, getCallingContext()) .WillOnce(Return(Access::CallingContext{ .uid = AID_ISOLATED_START, })); EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access)); sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(), Status::EX_SECURITY); } Loading