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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « services/service_manager/service_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/service_manager/service_manager.h" 5 #include "services/service_manager/service_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // Deletes |child|. 139 // Deletes |child|.
140 children_.erase(it); 140 children_.erase(it);
141 } 141 }
142 142
143 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { 143 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) {
144 if (!service_.is_bound()) 144 if (!service_.is_bound())
145 return false; 145 return false;
146 146
147 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); 147 std::unique_ptr<ConnectParams> params(std::move(*connect_params));
148 if (!params->connect_callback().is_null()) { 148 if (!params->connect_callback().is_null()) {
149 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, 149 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
150 identity_.user_id()); 150 identity_.user_id());
151 } 151 }
152 152
153 InterfaceProviderSpecMap specs; 153 InterfaceProviderSpecMap specs;
154 Instance* source = service_manager_->GetExistingInstance(params->source()); 154 Instance* source = service_manager_->GetExistingInstance(params->source());
155 if (source) 155 if (source)
156 specs = source->interface_provider_specs_; 156 specs = source->interface_provider_specs_;
157 157
158 pending_service_connections_++; 158 pending_service_connections_++;
159 service_->OnConnect(ServiceInfo(params->source(), specs), 159 service_->OnConnect(ServiceInfo(params->source(), specs),
160 params->TakeRemoteInterfaces(), 160 params->TakeRemoteInterfaces(),
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 mojom::Resolver* resolver = resolver_ptr.get(); 630 mojom::Resolver* resolver = resolver_ptr.get();
631 identity_to_resolver_[identity] = std::move(resolver_ptr); 631 identity_to_resolver_[identity] = std::move(resolver_ptr);
632 return resolver; 632 return resolver;
633 } 633 }
634 634
635 void ServiceManager::OnInstanceError(Instance* instance) { 635 void ServiceManager::OnInstanceError(Instance* instance) {
636 // We never clean up the ServiceManager's own instance. 636 // We never clean up the ServiceManager's own instance.
637 if (instance == service_manager_instance_) 637 if (instance == service_manager_instance_)
638 return; 638 return;
639 639
640 const Identity identity = instance->identity(); 640 EraseInstanceIdentity(instance);
641 identity_to_instance_.erase(identity);
642
643 if (instance->parent()) { 641 if (instance->parent()) {
644 // Deletes |instance|. 642 // Deletes |instance|.
645 instance->parent()->RemoveChild(instance); 643 instance->parent()->RemoveChild(instance);
646 } else { 644 } else {
647 auto it = root_instances_.find(instance); 645 auto it = root_instances_.find(instance);
648 DCHECK(it != root_instances_.end()); 646 DCHECK(it != root_instances_.end());
649 647
650 // Deletes |instance|. 648 // Deletes |instance|.
651 root_instances_.erase(it); 649 root_instances_.erase(it);
652 } 650 }
653 } 651 }
654 652
655 void ServiceManager::OnInstanceUnreachable(Instance* instance) { 653 void ServiceManager::OnInstanceUnreachable(Instance* instance) {
656 // If an Instance becomes unreachable, new connection requests for this 654 // If an Instance becomes unreachable, new connection requests for this
657 // identity will elicit a new Instance instantiation. The unreachable instance 655 // identity will elicit a new Instance instantiation. The unreachable instance
658 // remains alive. 656 // remains alive.
659 identity_to_instance_.erase(instance->identity()); 657 EraseInstanceIdentity(instance);
660 } 658 }
661 659
662 void ServiceManager::OnInstanceStopped(const Identity& identity) { 660 void ServiceManager::OnInstanceStopped(const Identity& identity) {
663 listeners_.ForAllPtrs([identity](mojom::ServiceManagerListener* listener) { 661 listeners_.ForAllPtrs([identity](mojom::ServiceManagerListener* listener) {
664 listener->OnServiceStopped(identity); 662 listener->OnServiceStopped(identity);
665 }); 663 });
666 if (!instance_quit_callback_.is_null()) 664 if (!instance_quit_callback_.is_null())
667 instance_quit_callback_.Run(identity); 665 instance_quit_callback_.Run(identity);
668 } 666 }
669 667
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 for (auto entry : identity_to_instance_) { 706 for (auto entry : identity_to_instance_) {
709 if (entry.first.name() == identity.name() && 707 if (entry.first.name() == identity.name() &&
710 entry.first.instance() == identity.instance()) { 708 entry.first.instance() == identity.instance()) {
711 return entry.second; 709 return entry.second;
712 } 710 }
713 } 711 }
714 } 712 }
715 return nullptr; 713 return nullptr;
716 } 714 }
717 715
716 void ServiceManager::EraseInstanceIdentity(Instance* instance) {
717 const Identity& identity = instance->identity();
718
719 auto it = identity_to_instance_.find(identity);
720 if (it != identity_to_instance_.end()) {
721 identity_to_instance_.erase(it);
722 return;
723 }
724
725 if (singletons_.find(identity.name()) != singletons_.end()) {
726 singletons_.erase(identity.name());
727 for (auto it = identity_to_instance_.begin();
728 it != identity_to_instance_.end(); ++it) {
729 if (it->first.name() == identity.name() &&
730 it->first.instance() == identity.instance()) {
731 identity_to_instance_.erase(it);
732 return;
733 }
734 }
735 }
736 }
737
718 void ServiceManager::NotifyServiceStarted(const Identity& identity, 738 void ServiceManager::NotifyServiceStarted(const Identity& identity,
719 base::ProcessId pid) { 739 base::ProcessId pid) {
720 listeners_.ForAllPtrs( 740 listeners_.ForAllPtrs(
721 [identity, pid](mojom::ServiceManagerListener* listener) { 741 [identity, pid](mojom::ServiceManagerListener* listener) {
722 listener->OnServiceStarted(identity, pid); 742 listener->OnServiceStarted(identity, pid);
723 }); 743 });
724 } 744 }
725 745
726 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { 746 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) {
727 listeners_.ForAllPtrs( 747 listeners_.ForAllPtrs(
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 // Now that the instance has a Service, we can connect to it. 956 // Now that the instance has a Service, we can connect to it.
937 bool connected = instance->ConnectToService(&params); 957 bool connected = instance->ConnectToService(&params);
938 DCHECK(connected); 958 DCHECK(connected);
939 } 959 }
940 960
941 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 961 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
942 return weak_ptr_factory_.GetWeakPtr(); 962 return weak_ptr_factory_.GetWeakPtr();
943 } 963 }
944 964
945 } // namespace service_manager 965 } // namespace service_manager
OLDNEW
« 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