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

Side by Side Diff: mojo/edk/system/node_channel.cc

Issue 1987423002: [mojo-edk] Add sanity checks to NodeChannel inputs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 7 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
« no previous file with comments | « no previous file | 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "mojo/edk/system/node_channel.h" 5 #include "mojo/edk/system/node_channel.h"
6 6
7 #include <cstring> 7 #include <cstring>
8 #include <limits> 8 #include <limits>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 Channel::MessagePtr message( 120 Channel::MessagePtr message(
121 new Channel::Message(sizeof(Header) + payload_size, num_handles)); 121 new Channel::Message(sizeof(Header) + payload_size, num_handles));
122 Header* header = reinterpret_cast<Header*>(message->mutable_payload()); 122 Header* header = reinterpret_cast<Header*>(message->mutable_payload());
123 header->type = type; 123 header->type = type;
124 header->padding = 0; 124 header->padding = 0;
125 *out_data = reinterpret_cast<DataType*>(&header[1]); 125 *out_data = reinterpret_cast<DataType*>(&header[1]);
126 return message; 126 return message;
127 } 127 }
128 128
129 template <typename DataType> 129 template <typename DataType>
130 void GetMessagePayload(const void* bytes, DataType** out_data) { 130 bool GetMessagePayload(const void* bytes,
131 size_t num_bytes,
132 DataType** out_data) {
133 static_assert(sizeof(DataType) > 0, "DataType must have non-zero size.");
134 if (num_bytes < sizeof(Header) + sizeof(DataType))
135 return false;
131 *out_data = reinterpret_cast<const DataType*>( 136 *out_data = reinterpret_cast<const DataType*>(
132 static_cast<const char*>(bytes) + sizeof(Header)); 137 static_cast<const char*>(bytes) + sizeof(Header));
138 return true;
133 } 139 }
134 140
135 } // namespace 141 } // namespace
136 142
137 // static 143 // static
138 scoped_refptr<NodeChannel> NodeChannel::Create( 144 scoped_refptr<NodeChannel> NodeChannel::Create(
139 Delegate* delegate, 145 Delegate* delegate,
140 ScopedPlatformHandle platform_handle, 146 ScopedPlatformHandle platform_handle,
141 scoped_refptr<base::TaskRunner> io_task_runner) { 147 scoped_refptr<base::TaskRunner> io_task_runner) {
142 return new NodeChannel(delegate, std::move(platform_handle), io_task_runner); 148 return new NodeChannel(delegate, std::move(platform_handle), io_task_runner);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 { 414 {
409 MachPortRelay* relay = delegate_->GetMachPortRelay(); 415 MachPortRelay* relay = delegate_->GetMachPortRelay();
410 if (handles && !relay) { 416 if (handles && !relay) {
411 if (!MachPortRelay::ReceivePorts(handles.get())) { 417 if (!MachPortRelay::ReceivePorts(handles.get())) {
412 LOG(ERROR) << "Error receiving mach ports."; 418 LOG(ERROR) << "Error receiving mach ports.";
413 } 419 }
414 } 420 }
415 } 421 }
416 #endif // defined(OS_WIN) 422 #endif // defined(OS_WIN)
417 423
424
425 if (payload_size <= sizeof(Header)) {
426 delegate_->OnChannelError(remote_node_name_);
427 return;
428 }
429
418 const Header* header = static_cast<const Header*>(payload); 430 const Header* header = static_cast<const Header*>(payload);
419 switch (header->type) { 431 switch (header->type) {
420 case MessageType::ACCEPT_CHILD: { 432 case MessageType::ACCEPT_CHILD: {
421 const AcceptChildData* data; 433 const AcceptChildData* data;
422 GetMessagePayload(payload, &data); 434 if (GetMessagePayload(payload, payload_size, &data)) {
423 delegate_->OnAcceptChild(remote_node_name_, data->parent_name, 435 delegate_->OnAcceptChild(remote_node_name_, data->parent_name,
424 data->token); 436 data->token);
437 return;
438 }
425 break; 439 break;
426 } 440 }
427 441
428 case MessageType::ACCEPT_PARENT: { 442 case MessageType::ACCEPT_PARENT: {
429 const AcceptParentData* data; 443 const AcceptParentData* data;
430 GetMessagePayload(payload, &data); 444 if (GetMessagePayload(payload, payload_size, &data)) {
431 delegate_->OnAcceptParent(remote_node_name_, data->token, 445 delegate_->OnAcceptParent(remote_node_name_, data->token,
432 data->child_name); 446 data->child_name);
447 return;
448 }
433 break; 449 break;
434 } 450 }
435 451
436 case MessageType::ADD_BROKER_CLIENT: { 452 case MessageType::ADD_BROKER_CLIENT: {
437 const AddBrokerClientData* data; 453 const AddBrokerClientData* data;
438 GetMessagePayload(payload, &data); 454 if (GetMessagePayload(payload, payload_size, &data)) {
439 ScopedPlatformHandle process_handle; 455 ScopedPlatformHandle process_handle;
440 #if defined(OS_WIN) 456 #if defined(OS_WIN)
441 if (!handles || handles->size() != 1) { 457 if (!handles || handles->size() != 1) {
442 DLOG(ERROR) << "Dropping invalid AddBrokerClient message."; 458 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
443 break; 459 break;
460 }
461 process_handle = ScopedPlatformHandle(handles->at(0));
462 handles->clear();
463 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
464 process_handle.release().handle);
465 #else
466 if (handles && handles->size() != 0) {
467 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
468 break;
469 }
470 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
471 data->process_handle);
472 #endif
473 return;
444 } 474 }
445 process_handle = ScopedPlatformHandle(handles->at(0));
446 handles->clear();
447 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
448 process_handle.release().handle);
449 #else
450 if (handles && handles->size() != 0) {
451 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
452 break;
453 }
454 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
455 data->process_handle);
456 #endif
457 break; 475 break;
458 } 476 }
459 477
460 case MessageType::BROKER_CLIENT_ADDED: { 478 case MessageType::BROKER_CLIENT_ADDED: {
461 const BrokerClientAddedData* data; 479 const BrokerClientAddedData* data;
462 GetMessagePayload(payload, &data); 480 if (GetMessagePayload(payload, payload_size, &data)) {
463 ScopedPlatformHandle broker_channel; 481 ScopedPlatformHandle broker_channel;
464 if (!handles || handles->size() != 1) { 482 if (!handles || handles->size() != 1) {
465 DLOG(ERROR) << "Dropping invalid BrokerClientAdded message."; 483 DLOG(ERROR) << "Dropping invalid BrokerClientAdded message.";
466 break; 484 break;
485 }
486 broker_channel = ScopedPlatformHandle(handles->at(0));
487 handles->clear();
488 delegate_->OnBrokerClientAdded(remote_node_name_, data->client_name,
489 std::move(broker_channel));
490 return;
467 } 491 }
468 broker_channel = ScopedPlatformHandle(handles->at(0));
469 handles->clear();
470 delegate_->OnBrokerClientAdded(remote_node_name_, data->client_name,
471 std::move(broker_channel));
472 break; 492 break;
473 } 493 }
474 494
475 case MessageType::ACCEPT_BROKER_CLIENT: { 495 case MessageType::ACCEPT_BROKER_CLIENT: {
476 const AcceptBrokerClientData* data; 496 const AcceptBrokerClientData* data;
477 GetMessagePayload(payload, &data); 497 if (GetMessagePayload(payload, payload_size, &data)) {
478 ScopedPlatformHandle broker_channel; 498 ScopedPlatformHandle broker_channel;
479 if (handles && handles->size() > 1) { 499 if (handles && handles->size() > 1) {
480 DLOG(ERROR) << "Dropping invalid AcceptBrokerClient message."; 500 DLOG(ERROR) << "Dropping invalid AcceptBrokerClient message.";
481 break; 501 break;
502 }
503 if (handles && handles->size() == 1) {
504 broker_channel = ScopedPlatformHandle(handles->at(0));
505 handles->clear();
506 }
507 delegate_->OnAcceptBrokerClient(remote_node_name_, data->broker_name,
508 std::move(broker_channel));
509 return;
482 } 510 }
483 if (handles && handles->size() == 1) {
484 broker_channel = ScopedPlatformHandle(handles->at(0));
485 handles->clear();
486 }
487 delegate_->OnAcceptBrokerClient(remote_node_name_, data->broker_name,
488 std::move(broker_channel));
489 break; 511 break;
490 } 512 }
491 513
492 case MessageType::PORTS_MESSAGE: { 514 case MessageType::PORTS_MESSAGE: {
493 size_t num_handles = handles ? handles->size() : 0; 515 size_t num_handles = handles ? handles->size() : 0;
494 Channel::MessagePtr message( 516 Channel::MessagePtr message(
495 new Channel::Message(payload_size, num_handles)); 517 new Channel::Message(payload_size, num_handles));
496 message->SetHandles(std::move(handles)); 518 message->SetHandles(std::move(handles));
497 memcpy(message->mutable_payload(), payload, payload_size); 519 memcpy(message->mutable_payload(), payload, payload_size);
498 delegate_->OnPortsMessage(std::move(message)); 520 delegate_->OnPortsMessage(std::move(message));
499 break; 521 return;
500 } 522 }
501 523
502 case MessageType::REQUEST_PORT_MERGE: { 524 case MessageType::REQUEST_PORT_MERGE: {
503 const RequestPortMergeData* data; 525 const RequestPortMergeData* data;
504 GetMessagePayload(payload, &data); 526 if (GetMessagePayload(payload, payload_size, &data)) {
505 527 // Don't accept an empty token.
506 const char* token_data = reinterpret_cast<const char*>(data + 1); 528 size_t token_size = payload_size - sizeof(*data) - sizeof(Header);
507 const size_t token_size = payload_size - sizeof(*data) - sizeof(Header); 529 if (token_size == 0)
508 std::string token(token_data, token_size); 530 break;
509 531 std::string token(reinterpret_cast<const char*>(data + 1), token_size);
510 delegate_->OnRequestPortMerge(remote_node_name_, 532 delegate_->OnRequestPortMerge(remote_node_name_,
511 data->connector_port_name, token); 533 data->connector_port_name, token);
534 return;
535 }
512 break; 536 break;
513 } 537 }
514 538
515 case MessageType::REQUEST_INTRODUCTION: { 539 case MessageType::REQUEST_INTRODUCTION: {
516 const IntroductionData* data; 540 const IntroductionData* data;
517 GetMessagePayload(payload, &data); 541 if (GetMessagePayload(payload, payload_size, &data)) {
518 delegate_->OnRequestIntroduction(remote_node_name_, data->name); 542 delegate_->OnRequestIntroduction(remote_node_name_, data->name);
543 return;
544 }
519 break; 545 break;
520 } 546 }
521 547
522 case MessageType::INTRODUCE: { 548 case MessageType::INTRODUCE: {
523 const IntroductionData* data; 549 const IntroductionData* data;
524 GetMessagePayload(payload, &data); 550 if (GetMessagePayload(payload, payload_size, &data)) {
525 if (handles && handles->size() > 1) { 551 if (handles && handles->size() > 1) {
526 DLOG(ERROR) << "Dropping invalid introduction message."; 552 DLOG(ERROR) << "Dropping invalid introduction message.";
527 break; 553 break;
554 }
555 ScopedPlatformHandle channel_handle;
556 if (handles && handles->size() == 1) {
557 channel_handle = ScopedPlatformHandle(handles->at(0));
558 handles->clear();
559 }
560 delegate_->OnIntroduce(remote_node_name_, data->name,
561 std::move(channel_handle));
562 return;
528 } 563 }
529 ScopedPlatformHandle channel_handle;
530 if (handles && handles->size() == 1) {
531 channel_handle = ScopedPlatformHandle(handles->at(0));
532 handles->clear();
533 }
534 delegate_->OnIntroduce(remote_node_name_, data->name,
535 std::move(channel_handle));
536 break; 564 break;
537 } 565 }
538 566
539 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS)) 567 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
540 case MessageType::RELAY_PORTS_MESSAGE: { 568 case MessageType::RELAY_PORTS_MESSAGE: {
541 base::ProcessHandle from_process; 569 base::ProcessHandle from_process;
542 { 570 {
543 base::AutoLock lock(remote_process_handle_lock_); 571 base::AutoLock lock(remote_process_handle_lock_);
544 from_process = remote_process_handle_; 572 from_process = remote_process_handle_;
545 } 573 }
546 const RelayPortsMessageData* data; 574 const RelayPortsMessageData* data;
547 GetMessagePayload(payload, &data); 575 if (GetMessagePayload(payload, payload_size, &data)) {
548 const void* message_start = data + 1; 576 // Don't try to relay an empty message.
549 Channel::MessagePtr message = Channel::Message::Deserialize( 577 if (payload_size <= sizeof(Header) + sizeof(RelayPortsMessageData))
550 message_start, payload_size - sizeof(Header) - sizeof(*data)); 578 break;
551 if (!message) { 579
552 DLOG(ERROR) << "Dropping invalid relay message."; 580 const void* message_start = data + 1;
553 break; 581 Channel::MessagePtr message = Channel::Message::Deserialize(
554 } 582 message_start, payload_size - sizeof(Header) - sizeof(*data));
555 #if defined(OS_MACOSX) && !defined(OS_IOS) 583 if (!message) {
556 message->SetHandles(std::move(handles)); 584 DLOG(ERROR) << "Dropping invalid relay message.";
557 MachPortRelay* relay = delegate_->GetMachPortRelay();
558 if (!relay) {
559 LOG(ERROR) << "Receiving mach ports without a port relay from "
560 << remote_node_name_ << ". Dropping message.";
561 break;
562 }
563 {
564 base::AutoLock lock(pending_mach_messages_lock_);
565 if (relay->port_provider()->TaskForPid(from_process) ==
566 MACH_PORT_NULL) {
567 pending_relay_messages_.push(
568 std::make_pair(data->destination, std::move(message)));
569 break; 585 break;
570 } 586 }
587 #if defined(OS_MACOSX) && !defined(OS_IOS)
588 message->SetHandles(std::move(handles));
589 MachPortRelay* relay = delegate_->GetMachPortRelay();
590 if (!relay) {
591 LOG(ERROR) << "Receiving mach ports without a port relay from "
592 << remote_node_name_ << ". Dropping message.";
593 break;
594 }
595 {
596 base::AutoLock lock(pending_mach_messages_lock_);
597 if (relay->port_provider()->TaskForPid(from_process) ==
598 MACH_PORT_NULL) {
599 pending_relay_messages_.push(
600 std::make_pair(data->destination, std::move(message)));
601 break;
602 }
603 }
604 #endif
605 delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
606 data->destination, std::move(message));
607 return;
571 } 608 }
572 #endif
573 delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
574 data->destination, std::move(message));
575 break; 609 break;
576 } 610 }
577 #endif 611 #endif
578 612
579 default: 613 default:
580 DLOG(ERROR) << "Received unknown message type "
581 << static_cast<uint32_t>(header->type) << " from node "
582 << remote_node_name_;
583 delegate_->OnChannelError(remote_node_name_);
584 break; 614 break;
585 } 615 }
616
617 DLOG(ERROR) << "Received invalid message. Closing channel.";
618 delegate_->OnChannelError(remote_node_name_);
586 } 619 }
587 620
588 void NodeChannel::OnChannelError() { 621 void NodeChannel::OnChannelError() {
589 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 622 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
590 623
591 RequestContext request_context(RequestContext::Source::SYSTEM); 624 RequestContext request_context(RequestContext::Source::SYSTEM);
592 625
593 ShutDown(); 626 ShutDown();
594 // |OnChannelError()| may cause |this| to be destroyed, but still need access 627 // |OnChannelError()| may cause |this| to be destroyed, but still need access
595 // to the name name after that destruction. So may a copy of 628 // to the name name after that destruction. So may a copy of
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 744
712 base::AutoLock lock(channel_lock_); 745 base::AutoLock lock(channel_lock_);
713 if (!channel_) 746 if (!channel_)
714 DLOG(ERROR) << "Dropping message on closed channel."; 747 DLOG(ERROR) << "Dropping message on closed channel.";
715 else 748 else
716 channel_->Write(std::move(message)); 749 channel_->Write(std::move(message));
717 } 750 }
718 751
719 } // namespace edk 752 } // namespace edk
720 } // namespace mojo 753 } // namespace mojo
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698