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

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

Issue 1977493004: [mojo-edk] Add sanity checks to NodeChannel inputs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 { 424 {
419 MachPortRelay* relay = delegate_->GetMachPortRelay(); 425 MachPortRelay* relay = delegate_->GetMachPortRelay();
420 if (handles && !relay) { 426 if (handles && !relay) {
421 if (!MachPortRelay::ReceivePorts(handles.get())) { 427 if (!MachPortRelay::ReceivePorts(handles.get())) {
422 LOG(ERROR) << "Error receiving mach ports."; 428 LOG(ERROR) << "Error receiving mach ports.";
423 } 429 }
424 } 430 }
425 } 431 }
426 #endif // defined(OS_WIN) 432 #endif // defined(OS_WIN)
427 433
434
435 if (payload_size <= sizeof(Header)) {
436 delegate_->OnChannelError(remote_node_name_);
437 return;
438 }
439
428 const Header* header = static_cast<const Header*>(payload); 440 const Header* header = static_cast<const Header*>(payload);
429 switch (header->type) { 441 switch (header->type) {
430 case MessageType::ACCEPT_CHILD: { 442 case MessageType::ACCEPT_CHILD: {
431 const AcceptChildData* data; 443 const AcceptChildData* data;
432 GetMessagePayload(payload, &data); 444 if (GetMessagePayload(payload, payload_size, &data)) {
433 delegate_->OnAcceptChild(remote_node_name_, data->parent_name, 445 delegate_->OnAcceptChild(remote_node_name_, data->parent_name,
434 data->token); 446 data->token);
447 return;
448 }
435 break; 449 break;
436 } 450 }
437 451
438 case MessageType::ACCEPT_PARENT: { 452 case MessageType::ACCEPT_PARENT: {
439 const AcceptParentData* data; 453 const AcceptParentData* data;
440 GetMessagePayload(payload, &data); 454 if (GetMessagePayload(payload, payload_size, &data)) {
441 delegate_->OnAcceptParent(remote_node_name_, data->token, 455 delegate_->OnAcceptParent(remote_node_name_, data->token,
442 data->child_name); 456 data->child_name);
457 return;
458 }
443 break; 459 break;
444 } 460 }
445 461
446 case MessageType::ADD_BROKER_CLIENT: { 462 case MessageType::ADD_BROKER_CLIENT: {
447 const AddBrokerClientData* data; 463 const AddBrokerClientData* data;
448 GetMessagePayload(payload, &data); 464 if (GetMessagePayload(payload, payload_size, &data)) {
449 ScopedPlatformHandle process_handle; 465 ScopedPlatformHandle process_handle;
450 #if defined(OS_WIN) 466 #if defined(OS_WIN)
451 if (!handles || handles->size() != 1) { 467 if (!handles || handles->size() != 1) {
452 DLOG(ERROR) << "Dropping invalid AddBrokerClient message."; 468 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
453 break; 469 break;
470 }
471 process_handle = ScopedPlatformHandle(handles->at(0));
472 handles->clear();
473 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
474 process_handle.release().handle);
475 #else
476 if (handles && handles->size() != 0) {
477 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
478 break;
479 }
480 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
481 data->process_handle);
482 #endif
483 return;
454 } 484 }
455 process_handle = ScopedPlatformHandle(handles->at(0));
456 handles->clear();
457 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
458 process_handle.release().handle);
459 #else
460 if (handles && handles->size() != 0) {
461 DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
462 break;
463 }
464 delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
465 data->process_handle);
466 #endif
467 break; 485 break;
468 } 486 }
469 487
470 case MessageType::BROKER_CLIENT_ADDED: { 488 case MessageType::BROKER_CLIENT_ADDED: {
471 const BrokerClientAddedData* data; 489 const BrokerClientAddedData* data;
472 GetMessagePayload(payload, &data); 490 if (GetMessagePayload(payload, payload_size, &data)) {
473 ScopedPlatformHandle broker_channel; 491 ScopedPlatformHandle broker_channel;
474 if (!handles || handles->size() != 1) { 492 if (!handles || handles->size() != 1) {
475 DLOG(ERROR) << "Dropping invalid BrokerClientAdded message."; 493 DLOG(ERROR) << "Dropping invalid BrokerClientAdded message.";
476 break; 494 break;
495 }
496 broker_channel = ScopedPlatformHandle(handles->at(0));
497 handles->clear();
498 delegate_->OnBrokerClientAdded(remote_node_name_, data->client_name,
499 std::move(broker_channel));
500 return;
477 } 501 }
478 broker_channel = ScopedPlatformHandle(handles->at(0));
479 handles->clear();
480 delegate_->OnBrokerClientAdded(remote_node_name_, data->client_name,
481 std::move(broker_channel));
482 break; 502 break;
483 } 503 }
484 504
485 case MessageType::ACCEPT_BROKER_CLIENT: { 505 case MessageType::ACCEPT_BROKER_CLIENT: {
486 const AcceptBrokerClientData* data; 506 const AcceptBrokerClientData* data;
487 GetMessagePayload(payload, &data); 507 if (GetMessagePayload(payload, payload_size, &data)) {
488 ScopedPlatformHandle broker_channel; 508 ScopedPlatformHandle broker_channel;
489 if (handles && handles->size() > 1) { 509 if (handles && handles->size() > 1) {
490 DLOG(ERROR) << "Dropping invalid AcceptBrokerClient message."; 510 DLOG(ERROR) << "Dropping invalid AcceptBrokerClient message.";
491 break; 511 break;
512 }
513 if (handles && handles->size() == 1) {
514 broker_channel = ScopedPlatformHandle(handles->at(0));
515 handles->clear();
516 }
517 delegate_->OnAcceptBrokerClient(remote_node_name_, data->broker_name,
518 std::move(broker_channel));
519 return;
492 } 520 }
493 if (handles && handles->size() == 1) {
494 broker_channel = ScopedPlatformHandle(handles->at(0));
495 handles->clear();
496 }
497 delegate_->OnAcceptBrokerClient(remote_node_name_, data->broker_name,
498 std::move(broker_channel));
499 break; 521 break;
500 } 522 }
501 523
502 case MessageType::PORTS_MESSAGE: { 524 case MessageType::PORTS_MESSAGE: {
503 size_t num_handles = handles ? handles->size() : 0; 525 size_t num_handles = handles ? handles->size() : 0;
504 Channel::MessagePtr message( 526 Channel::MessagePtr message(
505 new Channel::Message(payload_size, num_handles)); 527 new Channel::Message(payload_size, num_handles));
506 message->SetHandles(std::move(handles)); 528 message->SetHandles(std::move(handles));
507 memcpy(message->mutable_payload(), payload, payload_size); 529 memcpy(message->mutable_payload(), payload, payload_size);
508 delegate_->OnPortsMessage(std::move(message)); 530 delegate_->OnPortsMessage(std::move(message));
509 break; 531 return;
510 } 532 }
511 533
512 case MessageType::REQUEST_PORT_MERGE: { 534 case MessageType::REQUEST_PORT_MERGE: {
513 const RequestPortMergeData* data; 535 const RequestPortMergeData* data;
514 GetMessagePayload(payload, &data); 536 if (GetMessagePayload(payload, payload_size, &data)) {
515 537
516 const char* token_data = reinterpret_cast<const char*>(data + 1); 538 const char* token_data = reinterpret_cast<const char*>(data + 1);
517 const size_t token_size = payload_size - sizeof(*data) - sizeof(Header); 539 const size_t token_size = payload_size - sizeof(*data) - sizeof(Header);
518 std::string token(token_data, token_size); 540 std::string token(token_data, token_size);
Oliver Chang 2016/05/13 23:32:43 does it make sense for token_size to be 0 here?
519 541
520 delegate_->OnRequestPortMerge(remote_node_name_, 542 delegate_->OnRequestPortMerge(remote_node_name_,
521 data->connector_port_name, token); 543 data->connector_port_name, token);
544 return;
545 }
522 break; 546 break;
523 } 547 }
524 548
525 case MessageType::REQUEST_INTRODUCTION: { 549 case MessageType::REQUEST_INTRODUCTION: {
526 const IntroductionData* data; 550 const IntroductionData* data;
527 GetMessagePayload(payload, &data); 551 if (GetMessagePayload(payload, payload_size, &data)) {
528 delegate_->OnRequestIntroduction(remote_node_name_, data->name); 552 delegate_->OnRequestIntroduction(remote_node_name_, data->name);
553 return;
554 }
529 break; 555 break;
530 } 556 }
531 557
532 case MessageType::INTRODUCE: { 558 case MessageType::INTRODUCE: {
533 const IntroductionData* data; 559 const IntroductionData* data;
534 GetMessagePayload(payload, &data); 560 if (GetMessagePayload(payload, payload_size, &data)) {
535 if (handles && handles->size() > 1) { 561 if (handles && handles->size() > 1) {
536 DLOG(ERROR) << "Dropping invalid introduction message."; 562 DLOG(ERROR) << "Dropping invalid introduction message.";
537 break; 563 break;
564 }
565 ScopedPlatformHandle channel_handle;
566 if (handles && handles->size() == 1) {
567 channel_handle = ScopedPlatformHandle(handles->at(0));
568 handles->clear();
569 }
570 delegate_->OnIntroduce(remote_node_name_, data->name,
571 std::move(channel_handle));
572 return;
538 } 573 }
539 ScopedPlatformHandle channel_handle;
540 if (handles && handles->size() == 1) {
541 channel_handle = ScopedPlatformHandle(handles->at(0));
542 handles->clear();
543 }
544 delegate_->OnIntroduce(remote_node_name_, data->name,
545 std::move(channel_handle));
546 break; 574 break;
547 } 575 }
548 576
549 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS)) 577 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
550 case MessageType::RELAY_PORTS_MESSAGE: { 578 case MessageType::RELAY_PORTS_MESSAGE: {
551 base::ProcessHandle from_process; 579 base::ProcessHandle from_process;
552 { 580 {
553 base::AutoLock lock(remote_process_handle_lock_); 581 base::AutoLock lock(remote_process_handle_lock_);
554 from_process = remote_process_handle_; 582 from_process = remote_process_handle_;
555 } 583 }
556 const RelayPortsMessageData* data; 584 const RelayPortsMessageData* data;
557 GetMessagePayload(payload, &data); 585 if (GetMessagePayload(payload, payload_size, &data)) {
558 const void* message_start = data + 1; 586 // Don't try to relay an empty message.
559 Channel::MessagePtr message = Channel::Message::Deserialize( 587 if (payload_size <= sizeof(Header) + sizeof(RelayPortsMessageData))
560 message_start, payload_size - sizeof(Header) - sizeof(*data)); 588 break;
561 if (!message) { 589
562 DLOG(ERROR) << "Dropping invalid relay message."; 590 const void* message_start = data + 1;
563 break; 591 Channel::MessagePtr message = Channel::Message::Deserialize(
564 } 592 message_start, payload_size - sizeof(Header) - sizeof(*data));
565 #if defined(OS_MACOSX) && !defined(OS_IOS) 593 if (!message) {
566 message->SetHandles(std::move(handles)); 594 DLOG(ERROR) << "Dropping invalid relay message.";
567 MachPortRelay* relay = delegate_->GetMachPortRelay();
568 if (!relay) {
569 LOG(ERROR) << "Receiving mach ports without a port relay from "
570 << remote_node_name_ << ". Dropping message.";
571 break;
572 }
573 {
574 base::AutoLock lock(pending_mach_messages_lock_);
575 if (relay->port_provider()->TaskForPid(from_process) ==
576 MACH_PORT_NULL) {
577 pending_relay_messages_.push(
578 std::make_pair(data->destination, std::move(message)));
579 break; 595 break;
580 } 596 }
597 #if defined(OS_MACOSX) && !defined(OS_IOS)
598 message->SetHandles(std::move(handles));
599 MachPortRelay* relay = delegate_->GetMachPortRelay();
600 if (!relay) {
601 LOG(ERROR) << "Receiving mach ports without a port relay from "
602 << remote_node_name_ << ". Dropping message.";
603 break;
604 }
605 {
606 base::AutoLock lock(pending_mach_messages_lock_);
607 if (relay->port_provider()->TaskForPid(from_process) ==
608 MACH_PORT_NULL) {
609 pending_relay_messages_.push(
610 std::make_pair(data->destination, std::move(message)));
611 break;
612 }
613 }
614 #endif
615 delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
616 data->destination, std::move(message));
617 return;
581 } 618 }
582 #endif
583 delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
584 data->destination, std::move(message));
585 break; 619 break;
586 } 620 }
587 #endif 621 #endif
588 622
589 default: 623 default:
590 DLOG(ERROR) << "Received unknown message type "
591 << static_cast<uint32_t>(header->type) << " from node "
592 << remote_node_name_;
593 delegate_->OnChannelError(remote_node_name_);
594 break; 624 break;
595 } 625 }
626
627 DLOG(ERROR) << "Received invalid message. Closing channel.";
628 delegate_->OnChannelError(remote_node_name_);
596 } 629 }
597 630
598 void NodeChannel::OnChannelError() { 631 void NodeChannel::OnChannelError() {
599 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 632 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
600 633
601 RequestContext request_context(RequestContext::Source::SYSTEM); 634 RequestContext request_context(RequestContext::Source::SYSTEM);
602 635
603 ShutDown(); 636 ShutDown();
604 // |OnChannelError()| may cause |this| to be destroyed, but still need access 637 // |OnChannelError()| may cause |this| to be destroyed, but still need access
605 // to the name name after that destruction. So may a copy of 638 // to the name name after that destruction. So may a copy of
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 754
722 base::AutoLock lock(channel_lock_); 755 base::AutoLock lock(channel_lock_);
723 if (!channel_) 756 if (!channel_)
724 DLOG(ERROR) << "Dropping message on closed channel."; 757 DLOG(ERROR) << "Dropping message on closed channel.";
725 else 758 else
726 channel_->Write(std::move(message)); 759 channel_->Write(std::move(message));
727 } 760 }
728 761
729 } // namespace edk 762 } // namespace edk
730 } // namespace mojo 763 } // 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