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

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

Issue 1997453002: [mojo-edk] Better validation of untrusted message data (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 | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | 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/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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 if (header->num_bytes < header->num_header_bytes) { 135 if (header->num_bytes < header->num_header_bytes) {
136 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 136 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
137 << header->num_header_bytes; 137 << header->num_header_bytes;
138 return nullptr; 138 return nullptr;
139 } 139 }
140 140
141 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 141 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
142 #if defined(OS_WIN) 142 #if defined(OS_WIN)
143 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); 143 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle);
144 #elif defined(OS_MACOSX) && !defined(OS_IOS) 144 #elif defined(OS_MACOSX) && !defined(OS_IOS)
145 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry); 145 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
146 sizeof(MachPortsEntry);
146 #endif 147 #endif
147 if (header->num_handles > max_handles) { 148 if (header->num_handles > max_handles) {
148 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 149 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
149 << " > " << max_handles; 150 << " > " << max_handles;
150 return nullptr; 151 return nullptr;
151 } 152 }
152 153
153 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes, 154 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes,
154 max_handles)); 155 max_handles));
155 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 156 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
156 DCHECK_EQ(message->extra_header_size(), extra_header_size); 157 DCHECK_EQ(message->extra_header_size(), extra_header_size);
157 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 158 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes);
158 159
159 // Copy all payload bytes. 160 if (data_num_bytes > header->num_header_bytes) {
160 memcpy(message->mutable_payload(), 161 // Copy all payload bytes.
161 static_cast<const char*>(data) + header->num_header_bytes, 162 memcpy(message->mutable_payload(),
162 data_num_bytes - header->num_header_bytes); 163 static_cast<const char*>(data) + header->num_header_bytes,
163 // Copy extra header bytes. 164 data_num_bytes - header->num_header_bytes);
164 memcpy(message->mutable_extra_header(), 165 }
165 static_cast<const char*>(data) + sizeof(Header), 166
166 message->extra_header_size()); 167 if (message->extra_header_size()) {
168 // Copy extra header bytes.
169 memcpy(message->mutable_extra_header(),
170 static_cast<const char*>(data) + sizeof(Header),
171 message->extra_header_size());
172 }
173
167 message->header_->num_handles = header->num_handles; 174 message->header_->num_handles = header->num_handles;
168 175
169 return message; 176 return message;
170 #endif 177 #endif
171 } 178 }
172 179
173 size_t Channel::Message::payload_size() const { 180 size_t Channel::Message::payload_size() const {
174 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 181 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
175 return header_->num_bytes - sizeof(Header); 182 return header_->num_bytes - sizeof(Header);
176 #else 183 #else
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 return true; 485 return true;
479 } 486 }
480 487
481 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 488 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
482 size_t extra_header_size = 0; 489 size_t extra_header_size = 0;
483 const void* extra_header = nullptr; 490 const void* extra_header = nullptr;
484 size_t payload_size = header->num_bytes - sizeof(Message::Header); 491 size_t payload_size = header->num_bytes - sizeof(Message::Header);
485 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) 492 void* payload = payload_size ? const_cast<Message::Header*>(&header[1])
486 : nullptr; 493 : nullptr;
487 #else 494 #else
495 if (header->num_header_bytes < sizeof(Message::Header) ||
496 header->num_header_bytes > header->num_bytes) {
497 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes;
498 return false;
499 }
488 size_t extra_header_size = 500 size_t extra_header_size =
489 header->num_header_bytes - sizeof(Message::Header); 501 header->num_header_bytes - sizeof(Message::Header);
490 const void* extra_header = header + 1; 502 const void* extra_header = extra_header_size ? header + 1 : nullptr;
491 size_t payload_size = header->num_bytes - header->num_header_bytes; 503 size_t payload_size = header->num_bytes - header->num_header_bytes;
492 void* payload = 504 void* payload =
493 payload_size ? reinterpret_cast<Message::Header*>( 505 payload_size ? reinterpret_cast<Message::Header*>(
494 const_cast<char*>(read_buffer_->occupied_bytes()) + 506 const_cast<char*>(read_buffer_->occupied_bytes()) +
495 header->num_header_bytes) 507 header->num_header_bytes)
496 : nullptr; 508 : nullptr;
497 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) 509 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
498 510
499 ScopedPlatformHandleVectorPtr handles; 511 ScopedPlatformHandleVectorPtr handles;
500 if (header->num_handles > 0) { 512 if (header->num_handles > 0) {
501 handles = GetReadPlatformHandles(header->num_handles, extra_header, 513 if (!GetReadPlatformHandles(header->num_handles, extra_header,
502 extra_header_size); 514 extra_header_size, &handles)) {
515 return false;
516 }
517
503 if (!handles) { 518 if (!handles) {
504 // Not enough handles available for this message. 519 // Not enough handles available for this message.
505 break; 520 break;
506 } 521 }
507 } 522 }
508 523
509 // We've got a complete message! Dispatch it and try another. 524 // We've got a complete message! Dispatch it and try another.
510 if (header->message_type != Message::Header::MessageType::NORMAL) { 525 if (header->message_type != Message::Header::MessageType::NORMAL) {
511 OnControlMessage(header->message_type, payload, payload_size, 526 if (!OnControlMessage(header->message_type, payload, payload_size,
512 std::move(handles)); 527 std::move(handles))) {
528 return false;
529 }
513 did_dispatch_message = true; 530 did_dispatch_message = true;
514 } else if (delegate_) { 531 } else if (delegate_) {
515 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); 532 delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
516 did_dispatch_message = true; 533 did_dispatch_message = true;
517 } 534 }
518 535
519 read_buffer_->Discard(header->num_bytes); 536 read_buffer_->Discard(header->num_bytes);
520 } 537 }
521 538
522 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; 539 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
523 return true; 540 return true;
524 } 541 }
525 542
526 void Channel::OnError() { 543 void Channel::OnError() {
527 if (delegate_) 544 if (delegate_)
528 delegate_->OnChannelError(); 545 delegate_->OnChannelError();
529 } 546 }
530 547
548 bool Channel::OnControlMessage(Message::Header::MessageType message_type,
549 const void* payload,
550 size_t payload_size,
551 ScopedPlatformHandleVectorPtr handles) {
552 return false;
553 }
554
531 } // namespace edk 555 } // namespace edk
532 } // namespace mojo 556 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698