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

Side by Side Diff: services/service_manager/service_manager.cc

Issue 2816393002: Implement Connector::ApplySpec() & use to enforce navigation:frame (Closed)
Patch Set: . Created 3 years, 8 months 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
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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/guid.h" 13 #include "base/guid.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/process/process.h" 17 #include "base/process/process.h"
18 #include "base/process/process_handle.h" 18 #include "base/process/process_handle.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "mojo/public/cpp/bindings/associated_binding.h" 22 #include "mojo/public/cpp/bindings/associated_binding.h"
23 #include "mojo/public/cpp/bindings/binding.h" 23 #include "mojo/public/cpp/bindings/binding.h"
24 #include "mojo/public/cpp/bindings/binding_set.h" 24 #include "mojo/public/cpp/bindings/binding_set.h"
25 #include "mojo/public/cpp/bindings/strong_binding.h"
25 #include "services/catalog/public/interfaces/constants.mojom.h" 26 #include "services/catalog/public/interfaces/constants.mojom.h"
26 #include "services/service_manager/connect_util.h" 27 #include "services/service_manager/connect_util.h"
27 #include "services/service_manager/public/cpp/connector.h" 28 #include "services/service_manager/public/cpp/connector.h"
28 #include "services/service_manager/public/cpp/interface_registry.h" 29 #include "services/service_manager/public/cpp/interface_registry.h"
29 #include "services/service_manager/public/cpp/service.h" 30 #include "services/service_manager/public/cpp/service.h"
30 #include "services/service_manager/public/cpp/service_context.h" 31 #include "services/service_manager/public/cpp/service_context.h"
31 #include "services/service_manager/public/interfaces/connector.mojom.h" 32 #include "services/service_manager/public/interfaces/connector.mojom.h"
32 #include "services/service_manager/public/interfaces/constants.mojom.h" 33 #include "services/service_manager/public/interfaces/constants.mojom.h"
33 #include "services/service_manager/public/interfaces/service.mojom.h" 34 #include "services/service_manager/public/interfaces/service.mojom.h"
34 #include "services/service_manager/public/interfaces/service_control.mojom.h" 35 #include "services/service_manager/public/interfaces/service_control.mojom.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 71 }
71 72
72 bool HasCapability(const InterfaceProviderSpec& spec, 73 bool HasCapability(const InterfaceProviderSpec& spec,
73 const std::string& capability) { 74 const std::string& capability) {
74 auto it = spec.requires.find(service_manager::mojom::kServiceName); 75 auto it = spec.requires.find(service_manager::mojom::kServiceName);
75 if (it == spec.requires.end()) 76 if (it == spec.requires.end())
76 return false; 77 return false;
77 return it->second.find(capability) != it->second.end(); 78 return it->second.find(capability) != it->second.end();
78 } 79 }
79 80
81 bool AllowsInterface(const Identity& source,
82 const InterfaceProviderSpec& source_spec,
83 const Identity& target,
84 const InterfaceProviderSpec& target_spec,
85 const std::string& interface_name) {
86 InterfaceSet exposed =
87 GetInterfacesToExpose(source_spec, target, target_spec);
88 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) ||
89 exposed.count(interface_name) > 0;
90 if (!allowed) {
91 std::stringstream ss;
92 ss << "Connection InterfaceProviderSpec prevented service: "
93 << source.name() << " from binding interface: " << interface_name
94 << " exposed by: " << target.name();
95 LOG(ERROR) << ss.str();
96 }
97 return allowed;
98 }
99
80 // Encapsulates a connection to an instance of a service, tracked by the 100 // Encapsulates a connection to an instance of a service, tracked by the
81 // Service Manager. 101 // Service Manager.
82 class ServiceManager::Instance 102 class ServiceManager::Instance
83 : public mojom::Connector, 103 : public mojom::Connector,
84 public mojom::PIDReceiver, 104 public mojom::PIDReceiver,
85 public Service, 105 public Service,
86 public mojom::ServiceManager, 106 public mojom::ServiceManager,
87 public mojom::ServiceControl { 107 public mojom::ServiceControl {
88 public: 108 public:
89 Instance(service_manager::ServiceManager* service_manager, 109 Instance(service_manager::ServiceManager* service_manager,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 std::unique_ptr<ConnectParams> params(std::move(*in_params)); 158 std::unique_ptr<ConnectParams> params(std::move(*in_params));
139 InterfaceProviderSpecMap source_specs; 159 InterfaceProviderSpecMap source_specs;
140 InterfaceProviderSpec source_connection_spec; 160 InterfaceProviderSpec source_connection_spec;
141 Instance* source = 161 Instance* source =
142 service_manager_->GetExistingInstance(params->source()); 162 service_manager_->GetExistingInstance(params->source());
143 if (source) { 163 if (source) {
144 source_specs = source->interface_provider_specs_; 164 source_specs = source->interface_provider_specs_;
145 source_connection_spec = source->GetConnectionSpec(); 165 source_connection_spec = source->GetConnectionSpec();
146 } 166 }
147 167
148 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, 168 if (!AllowsInterface(params->source(), source_connection_spec, identity_,
149 identity_, 169 GetConnectionSpec(), params->interface_name())) {
150 GetConnectionSpec());
151 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) ||
152 exposed.count(params->interface_name()) > 0;
153 if (!allowed) {
154 std::stringstream ss;
155 ss << "Connection InterfaceProviderSpec prevented service: "
156 << params->source().name() << " from binding interface: "
157 << params->interface_name() << " exposed by: " << identity_.name();
158 LOG(ERROR) << ss.str();
159 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); 170 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_);
160 return false; 171 return false;
161 } 172 }
162 173
163 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_); 174 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_);
164 175
165 pending_service_connections_++; 176 pending_service_connections_++;
166 service_->OnBindInterface( 177 service_->OnBindInterface(
167 ServiceInfo(params->source(), source_specs), 178 ServiceInfo(params->source(), source_specs),
168 params->interface_name(), 179 params->interface_name(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 219
209 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { 220 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const {
210 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); 221 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New());
211 info->id = id_; 222 info->id = id_;
212 info->identity = identity_; 223 info->identity = identity_;
213 info->pid = pid_; 224 info->pid = pid_;
214 return info; 225 return info;
215 } 226 }
216 227
217 const InterfaceProviderSpec& GetConnectionSpec() const { 228 const InterfaceProviderSpec& GetConnectionSpec() const {
218 auto it = interface_provider_specs_.find( 229 return GetSpecNamed(mojom::kServiceManager_ConnectorSpec);
219 mojom::kServiceManager_ConnectorSpec); 230 }
231 bool HasSpecNamed(const std::string& spec) const {
Ken Rockot(use gerrit already) 2017/04/26 04:32:48 nits: GetSpec and HasSpec? And vertical whitespace
232 auto it = interface_provider_specs_.find(spec);
233 return it != interface_provider_specs_.end();
234 }
235 const InterfaceProviderSpec& GetSpecNamed(const std::string& spec) const {
236 auto it = interface_provider_specs_.find(spec);
220 return it != interface_provider_specs_.end() ? it->second : empty_spec_; 237 return it != interface_provider_specs_.end() ? it->second : empty_spec_;
221 } 238 }
239
222 const Identity& identity() const { return identity_; } 240 const Identity& identity() const { return identity_; }
223 void set_identity(const Identity& identity) { identity_ = identity; } 241 void set_identity(const Identity& identity) { identity_ = identity; }
224 uint32_t id() const { return id_; } 242 uint32_t id() const { return id_; }
225 243
226 // Service: 244 // Service:
227 void OnBindInterface(const ServiceInfo& source_info, 245 void OnBindInterface(const ServiceInfo& source_info,
228 const std::string& interface_name, 246 const std::string& interface_name,
229 mojo::ScopedMessagePipeHandle interface_pipe) override { 247 mojo::ScopedMessagePipeHandle interface_pipe) override {
230 Instance* source = 248 Instance* source =
231 service_manager_->GetExistingInstance(source_info.identity); 249 service_manager_->GetExistingInstance(source_info.identity);
232 DCHECK(source); 250 DCHECK(source);
233 if (interface_name == mojom::ServiceManager::Name_ && 251 if (interface_name == mojom::ServiceManager::Name_ &&
234 HasCapability(source->GetConnectionSpec(), 252 HasCapability(source->GetConnectionSpec(),
235 kCapability_ServiceManager)) { 253 kCapability_ServiceManager)) {
236 mojom::ServiceManagerRequest request = 254 mojom::ServiceManagerRequest request =
237 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe)); 255 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe));
238 service_manager_bindings_.AddBinding(this, std::move(request)); 256 service_manager_bindings_.AddBinding(this, std::move(request));
239 } 257 }
240 } 258 }
241 259
242 private: 260 private:
243 enum class State { 261 enum class State {
244 // The service was not started yet. 262 // The service was not started yet.
245 IDLE, 263 IDLE,
246 264
247 // The service was started but the service manager hasn't received the 265 // The service was started but the service manager hasn't received the
248 // initial response from it yet. 266 // initial response from it yet.
249 STARTING, 267 STARTING,
250 268
251 // The service was started successfully. 269 // The service was started successfully.
252 STARTED 270 STARTED
253 }; 271 };
254 272
273 class InterfaceProviderImpl : public mojom::InterfaceProvider {
274 public:
275 InterfaceProviderImpl(const std::string& spec,
276 const Identity& source_identity,
277 const Identity& target_identity,
278 service_manager::ServiceManager* service_manager,
279 mojom::InterfaceProviderPtr target)
280 : spec_(spec),
281 source_identity_(source_identity),
282 target_identity_(target_identity),
283 service_manager_(service_manager),
284 target_(std::move(target)) {}
285 ~InterfaceProviderImpl() override {}
286
287 private:
288 // mojom::InterfaceProvider:
289 void GetInterface(const std::string& interface_name,
290 mojo::ScopedMessagePipeHandle interface_pipe) override {
291 Instance* source =
292 service_manager_->GetExistingInstance(source_identity_);
293 Instance* target =
294 service_manager_->GetExistingInstance(target_identity_);
295 if (!source || !target)
296 return;
297 if (!ValidateSpec(source) || !ValidateSpec(target))
298 return;
299
300 if (AllowsInterface(source_identity_, source->GetSpecNamed(spec_),
301 target_identity_, target->GetSpecNamed(spec_),
302 interface_name)) {
303 target_->GetInterface(interface_name, std::move(interface_pipe));
304 }
305 }
306
307 bool ValidateSpec(Instance* instance) const {
308 if (!instance->HasSpecNamed(spec_)) {
309 LOG(ERROR) << "Instance for: " << instance->identity().name()
310 << " did not have spec named: " << spec_;
311 return false;
312 }
313 return true;
314 }
315
316 const std::string spec_;
317 const Identity source_identity_;
318 const Identity target_identity_;
319 service_manager::ServiceManager* service_manager_;
Ken Rockot(use gerrit already) 2017/04/26 04:32:48 nit: this could be const too (service_manager::Ser
320
321 mojom::InterfaceProviderPtr target_;
322
323 DISALLOW_COPY_AND_ASSIGN(InterfaceProviderImpl);
324 };
325
255 // mojom::Connector implementation: 326 // mojom::Connector implementation:
256 void BindInterface(const service_manager::Identity& in_target, 327 void BindInterface(const service_manager::Identity& in_target,
257 const std::string& interface_name, 328 const std::string& interface_name,
258 mojo::ScopedMessagePipeHandle interface_pipe, 329 mojo::ScopedMessagePipeHandle interface_pipe,
259 const BindInterfaceCallback& callback) override { 330 const BindInterfaceCallback& callback) override {
260 Identity target = in_target; 331 Identity target = in_target;
261 mojom::ConnectResult result = 332 mojom::ConnectResult result =
262 ValidateConnectParams(&target, nullptr, nullptr); 333 ValidateConnectParams(&target, nullptr, nullptr);
263 if (!Succeeded(result)) { 334 if (!Succeeded(result)) {
264 callback.Run(result, Identity()); 335 callback.Run(result, Identity());
265 return; 336 return;
266 } 337 }
267 338
268 std::unique_ptr<ConnectParams> params(new ConnectParams); 339 std::unique_ptr<ConnectParams> params(new ConnectParams);
269 params->set_source(identity_); 340 params->set_source(identity_);
270 params->set_target(target); 341 params->set_target(target);
271 params->set_interface_request_info(interface_name, 342 params->set_interface_request_info(interface_name,
272 std::move(interface_pipe)); 343 std::move(interface_pipe));
273 params->set_start_service_callback(callback); 344 params->set_start_service_callback(callback);
274 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 345 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
275 } 346 }
276 347
277 void StartService(const Identity& in_target, 348 void StartService(const Identity& in_target,
278 const StartServiceCallback& callback) override { 349 const StartServiceCallback& callback) override {
279 Identity target = in_target; 350 Identity target = in_target;
280 mojom::ConnectResult result = 351 mojom::ConnectResult result =
281 ValidateConnectParams(&target, nullptr, nullptr); 352 ValidateConnectParams(&target, nullptr, nullptr);
282 if (!Succeeded(result)) { 353 if (!Succeeded(result)) {
283 callback.Run(result, Identity()); 354 callback.Run(result, Identity());
284 return; 355 return;
285 } 356 }
286 357
287 std::unique_ptr<ConnectParams> params(new ConnectParams); 358 std::unique_ptr<ConnectParams> params(new ConnectParams);
288 params->set_source(identity_); 359 params->set_source(identity_);
289 params->set_target(target); 360 params->set_target(target);
290 params->set_start_service_callback(callback); 361 params->set_start_service_callback(callback);
291 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 362 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
292 } 363 }
293 364
294 void StartServiceWithProcess( 365 void StartServiceWithProcess(
295 const Identity& in_target, 366 const Identity& in_target,
296 mojo::ScopedMessagePipeHandle service_handle, 367 mojo::ScopedMessagePipeHandle service_handle,
297 mojom::PIDReceiverRequest pid_receiver_request, 368 mojom::PIDReceiverRequest pid_receiver_request,
298 const StartServiceWithProcessCallback& callback) override { 369 const StartServiceWithProcessCallback& callback) override {
299 Identity target = in_target; 370 Identity target = in_target;
300 mojom::ConnectResult result = 371 mojom::ConnectResult result =
301 ValidateConnectParams(&target, nullptr, nullptr); 372 ValidateConnectParams(&target, nullptr, nullptr);
302 if (!Succeeded(result)) { 373 if (!Succeeded(result)) {
303 callback.Run(result, Identity()); 374 callback.Run(result, Identity());
304 return; 375 return;
305 } 376 }
306 377
307 std::unique_ptr<ConnectParams> params(new ConnectParams); 378 std::unique_ptr<ConnectParams> params(new ConnectParams);
308 params->set_source(identity_); 379 params->set_source(identity_);
309 params->set_target(target); 380 params->set_target(target);
310 381
311 mojom::ServicePtr service; 382 mojom::ServicePtr service;
312 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); 383 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0));
313 params->set_client_process_info(std::move(service), 384 params->set_client_process_info(std::move(service),
314 std::move(pid_receiver_request)); 385 std::move(pid_receiver_request));
315 params->set_start_service_callback(callback); 386 params->set_start_service_callback(callback);
316 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 387 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
317 } 388 }
318 389
319 void Clone(mojom::ConnectorRequest request) override { 390 void Clone(mojom::ConnectorRequest request) override {
320 connectors_.AddBinding(this, std::move(request)); 391 connectors_.AddBinding(this, std::move(request));
321 } 392 }
322 393
394 void ApplySpec(const std::string& spec,
395 const Identity& source,
396 mojom::InterfaceProviderRequest source_request,
397 mojom::InterfaceProviderPtr target) override {
398 mojo::MakeStrongBinding(
Ken Rockot(use gerrit already) 2017/04/26 04:32:48 It's not safe to use StrongBinding here if you're
399 base::MakeUnique<InterfaceProviderImpl>(
400 spec, source, identity_, service_manager_, std::move(target)),
401 std::move(source_request));
402 }
403
323 // mojom::PIDReceiver: 404 // mojom::PIDReceiver:
324 void SetPID(uint32_t pid) override { 405 void SetPID(uint32_t pid) override {
325 PIDAvailable(pid); 406 PIDAvailable(pid);
326 } 407 }
327 408
328 // mojom::ServiceManager implementation: 409 // mojom::ServiceManager implementation:
329 void AddListener(mojom::ServiceManagerListenerPtr listener) override { 410 void AddListener(mojom::ServiceManagerListenerPtr listener) override {
330 // TODO(beng): this should only track the instances matching this user, and 411 // TODO(beng): this should only track the instances matching this user, and
331 // root. 412 // root.
332 service_manager_->AddListener(std::move(listener)); 413 service_manager_->AddListener(std::move(listener));
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 instance->identity()); 1081 instance->identity());
1001 if (params->HasInterfaceRequestInfo()) 1082 if (params->HasInterfaceRequestInfo())
1002 instance->CallOnBindInterface(&params); 1083 instance->CallOnBindInterface(&params);
1003 } 1084 }
1004 1085
1005 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 1086 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
1006 return weak_ptr_factory_.GetWeakPtr(); 1087 return weak_ptr_factory_.GetWeakPtr();
1007 } 1088 }
1008 1089
1009 } // namespace service_manager 1090 } // namespace service_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698