Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/channel.h" | 5 #include "mojo/edk/system/channel.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 if (header->num_bytes < header->num_header_bytes) { | 143 if (header->num_bytes < header->num_header_bytes) { |
| 144 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " | 144 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " |
| 145 << header->num_header_bytes; | 145 << header->num_header_bytes; |
| 146 return nullptr; | 146 return nullptr; |
| 147 } | 147 } |
| 148 | 148 |
| 149 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); | 149 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); |
| 150 #if defined(OS_WIN) | 150 #if defined(OS_WIN) |
| 151 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); | 151 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); |
| 152 #elif defined(OS_MACOSX) && !defined(OS_IOS) | 152 #elif defined(OS_MACOSX) && !defined(OS_IOS) |
| 153 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry); | 153 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry); |
|
Anand Mistry (off Chromium)
2016/05/16 04:27:48
Hm. This reminds me. This check is incorrect. It s
Ken Rockot(use gerrit already)
2016/05/16 04:39:14
Done
| |
| 154 #endif | 154 #endif |
| 155 if (header->num_handles > max_handles) { | 155 if (header->num_handles > max_handles) { |
| 156 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles | 156 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles |
| 157 << " > " << max_handles; | 157 << " > " << max_handles; |
| 158 return nullptr; | 158 return nullptr; |
| 159 } | 159 } |
| 160 | 160 |
| 161 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes, | 161 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes, |
| 162 max_handles)); | 162 max_handles)); |
| 163 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); | 163 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); |
| 164 DCHECK_EQ(message->extra_header_size(), extra_header_size); | 164 DCHECK_EQ(message->extra_header_size(), extra_header_size); |
| 165 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); | 165 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); |
| 166 | 166 |
| 167 // Copy all payload bytes. | 167 if (data_num_bytes > header->num_header_bytes) { |
|
Anand Mistry (off Chromium)
2016/05/16 04:27:48
These only protect against 0-byte memcpy's, which
Ken Rockot(use gerrit already)
2016/05/16 04:39:14
Yeah - mostly I'm just uncomfortable with ever pas
| |
| 168 memcpy(message->mutable_payload(), | 168 // Copy all payload bytes. |
| 169 static_cast<const char*>(data) + header->num_header_bytes, | 169 memcpy(message->mutable_payload(), |
| 170 data_num_bytes - header->num_header_bytes); | 170 static_cast<const char*>(data) + header->num_header_bytes, |
| 171 // Copy extra header bytes. | 171 data_num_bytes - header->num_header_bytes); |
| 172 memcpy(message->mutable_extra_header(), | 172 } |
| 173 static_cast<const char*>(data) + sizeof(Header), | 173 |
| 174 message->extra_header_size()); | 174 if (message->extra_header_size()) { |
| 175 // Copy extra header bytes. | |
| 176 memcpy(message->mutable_extra_header(), | |
| 177 static_cast<const char*>(data) + sizeof(Header), | |
| 178 message->extra_header_size()); | |
| 179 } | |
| 180 | |
| 175 message->header_->num_handles = header->num_handles; | 181 message->header_->num_handles = header->num_handles; |
| 176 | 182 |
| 177 return message; | 183 return message; |
| 178 #endif | 184 #endif |
| 179 } | 185 } |
| 180 | 186 |
| 181 size_t Channel::Message::payload_size() const { | 187 size_t Channel::Message::payload_size() const { |
| 182 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 188 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) |
| 183 return header_->num_bytes - sizeof(Header); | 189 return header_->num_bytes - sizeof(Header); |
| 184 #else | 190 #else |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 return true; | 529 return true; |
| 524 } | 530 } |
| 525 | 531 |
| 526 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 532 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) |
| 527 size_t extra_header_size = 0; | 533 size_t extra_header_size = 0; |
| 528 const void* extra_header = nullptr; | 534 const void* extra_header = nullptr; |
| 529 size_t payload_size = header->num_bytes - sizeof(Message::Header); | 535 size_t payload_size = header->num_bytes - sizeof(Message::Header); |
| 530 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) | 536 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) |
| 531 : nullptr; | 537 : nullptr; |
| 532 #else | 538 #else |
| 539 if (header->num_header_bytes < sizeof(Message::Header) || | |
| 540 header->num_header_bytes > header->num_bytes) | |
|
Anand Mistry (off Chromium)
2016/05/16 04:27:48
Can you add a LOG(ERROR) here, similar to the one
Ken Rockot(use gerrit already)
2016/05/16 04:39:14
Done - though this can certainly happen with a mal
Anand Mistry (off Chromium)
2016/05/16 04:45:50
Thanks. I'm assuming malicious input is not normal
| |
| 541 return false; | |
| 533 size_t extra_header_size = | 542 size_t extra_header_size = |
| 534 header->num_header_bytes - sizeof(Message::Header); | 543 header->num_header_bytes - sizeof(Message::Header); |
| 535 const void* extra_header = header + 1; | 544 const void* extra_header = extra_header_size ? header + 1 : nullptr; |
| 536 size_t payload_size = header->num_bytes - header->num_header_bytes; | 545 size_t payload_size = header->num_bytes - header->num_header_bytes; |
| 537 void* payload = | 546 void* payload = |
| 538 payload_size ? reinterpret_cast<Message::Header*>( | 547 payload_size ? reinterpret_cast<Message::Header*>( |
| 539 const_cast<char*>(read_buffer_->occupied_bytes()) + | 548 const_cast<char*>(read_buffer_->occupied_bytes()) + |
| 540 header->num_header_bytes) | 549 header->num_header_bytes) |
| 541 : nullptr; | 550 : nullptr; |
| 542 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) | 551 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) |
| 543 | 552 |
| 544 ScopedPlatformHandleVectorPtr handles; | 553 ScopedPlatformHandleVectorPtr handles; |
| 545 if (header->num_handles > 0) { | 554 if (header->num_handles > 0) { |
| 546 handles = GetReadPlatformHandles(header->num_handles, extra_header, | 555 if (!GetReadPlatformHandles(header->num_handles, extra_header, |
| 547 extra_header_size); | 556 extra_header_size, &handles)) { |
| 557 return false; | |
| 558 } | |
| 559 | |
| 548 if (!handles) { | 560 if (!handles) { |
| 549 // Not enough handles available for this message. | 561 // Not enough handles available for this message. |
| 550 break; | 562 break; |
| 551 } | 563 } |
| 552 } | 564 } |
| 553 | 565 |
| 554 // We've got a complete message! Dispatch it and try another. | 566 // We've got a complete message! Dispatch it and try another. |
| 555 if (header->message_type != Message::Header::MessageType::NORMAL) { | 567 if (header->message_type != Message::Header::MessageType::NORMAL) { |
| 556 OnControlMessage(header->message_type, payload, payload_size, | 568 if (!OnControlMessage(header->message_type, payload, payload_size, |
| 557 std::move(handles)); | 569 std::move(handles))) { |
| 570 return false; | |
| 571 } | |
| 558 did_dispatch_message = true; | 572 did_dispatch_message = true; |
| 559 } else if (delegate_) { | 573 } else if (delegate_) { |
| 560 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); | 574 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); |
| 561 did_dispatch_message = true; | 575 did_dispatch_message = true; |
| 562 } | 576 } |
| 563 | 577 |
| 564 read_buffer_->Discard(header->num_bytes); | 578 read_buffer_->Discard(header->num_bytes); |
| 565 } | 579 } |
| 566 | 580 |
| 567 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; | 581 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; |
| 568 return true; | 582 return true; |
| 569 } | 583 } |
| 570 | 584 |
| 571 void Channel::OnError() { | 585 void Channel::OnError() { |
| 572 if (delegate_) | 586 if (delegate_) |
| 573 delegate_->OnChannelError(); | 587 delegate_->OnChannelError(); |
| 574 } | 588 } |
| 575 | 589 |
| 590 bool Channel::OnControlMessage(Message::Header::MessageType message_type, | |
| 591 const void* payload, | |
| 592 size_t payload_size, | |
| 593 ScopedPlatformHandleVectorPtr handles) { | |
| 594 return false; | |
| 595 } | |
| 596 | |
| 576 } // namespace edk | 597 } // namespace edk |
| 577 } // namespace mojo | 598 } // namespace mojo |
| OLD | NEW |