Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Unified Diff: services/service_manager/service_manager.cc

Issue 2566663003: Fix UAF on singleton service instances (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/service_manager/service_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/service_manager/service_manager.cc
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc
index dab2bd76dabab389e0279c67231b44db501aca2f..fc5160942ce53c85abd26f3a96a7a712929c33ff 100644
--- a/services/service_manager/service_manager.cc
+++ b/services/service_manager/service_manager.cc
@@ -146,8 +146,8 @@ class ServiceManager::Instance
std::unique_ptr<ConnectParams> params(std::move(*connect_params));
if (!params->connect_callback().is_null()) {
- params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
- identity_.user_id());
+ params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
+ identity_.user_id());
}
InterfaceProviderSpecMap specs;
@@ -637,9 +637,7 @@ void ServiceManager::OnInstanceError(Instance* instance) {
if (instance == service_manager_instance_)
return;
- const Identity identity = instance->identity();
- identity_to_instance_.erase(identity);
-
+ EraseInstanceIdentity(instance);
if (instance->parent()) {
// Deletes |instance|.
instance->parent()->RemoveChild(instance);
@@ -656,7 +654,7 @@ void ServiceManager::OnInstanceUnreachable(Instance* instance) {
// If an Instance becomes unreachable, new connection requests for this
// identity will elicit a new Instance instantiation. The unreachable instance
// remains alive.
- identity_to_instance_.erase(instance->identity());
+ EraseInstanceIdentity(instance);
}
void ServiceManager::OnInstanceStopped(const Identity& identity) {
@@ -715,6 +713,28 @@ ServiceManager::Instance* ServiceManager::GetExistingInstance(
return nullptr;
}
+void ServiceManager::EraseInstanceIdentity(Instance* instance) {
+ const Identity& identity = instance->identity();
+
+ auto it = identity_to_instance_.find(identity);
+ if (it != identity_to_instance_.end()) {
+ identity_to_instance_.erase(it);
+ return;
+ }
+
+ if (singletons_.find(identity.name()) != singletons_.end()) {
+ singletons_.erase(identity.name());
+ for (auto it = identity_to_instance_.begin();
+ it != identity_to_instance_.end(); ++it) {
+ if (it->first.name() == identity.name() &&
+ it->first.instance() == identity.instance()) {
+ identity_to_instance_.erase(it);
+ return;
+ }
+ }
+ }
+}
+
void ServiceManager::NotifyServiceStarted(const Identity& identity,
base::ProcessId pid) {
listeners_.ForAllPtrs(
« no previous file with comments | « services/service_manager/service_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698