event.cc (21294B)
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 3 // found in the LICENSE file. 4 5 #include "mojo/core/ports/event.h" 6 7 #include <stdint.h> 8 #include <string.h> 9 10 #include "base/logging.h" 11 #include "mojo/core/ports/name.h" 12 #include "mojo/core/ports/user_message.h" 13 #include "mozilla/Assertions.h" 14 #include "mozilla/CheckedInt.h" 15 16 namespace mojo { 17 namespace core { 18 namespace ports { 19 20 namespace { 21 22 const size_t kPortsMessageAlignment = 8; 23 24 #pragma pack(push, 1) 25 26 struct SerializedHeader { 27 Event::Type type; 28 uint32_t padding; 29 PortName port_name; 30 PortName from_port; 31 uint64_t control_sequence_num; 32 }; 33 34 struct UserMessageEventData { 35 uint64_t sequence_num; 36 uint32_t num_ports; 37 uint32_t padding; 38 }; 39 40 struct ObserveProxyEventData { 41 NodeName proxy_node_name; 42 PortName proxy_port_name; 43 NodeName proxy_target_node_name; 44 PortName proxy_target_port_name; 45 }; 46 47 struct ObserveProxyAckEventData { 48 uint64_t last_sequence_num; 49 }; 50 51 struct ObserveClosureEventData { 52 uint64_t last_sequence_num; 53 }; 54 55 struct MergePortEventData { 56 PortName new_port_name; 57 Event::PortDescriptor new_port_descriptor; 58 }; 59 60 struct UserMessageReadAckRequestEventData { 61 uint64_t sequence_num_to_acknowledge; 62 }; 63 64 struct UserMessageReadAckEventData { 65 uint64_t sequence_num_acknowledged; 66 }; 67 68 struct UpdatePreviousPeerEventData { 69 NodeName new_node_name; 70 PortName new_port_name; 71 }; 72 73 #pragma pack(pop) 74 75 static_assert(sizeof(Event::PortDescriptor) % kPortsMessageAlignment == 0, 76 "Invalid PortDescriptor size."); 77 78 static_assert(sizeof(SerializedHeader) % kPortsMessageAlignment == 0, 79 "Invalid SerializedHeader size."); 80 81 static_assert(sizeof(UserMessageEventData) % kPortsMessageAlignment == 0, 82 "Invalid UserEventData size."); 83 84 static_assert(sizeof(ObserveProxyEventData) % kPortsMessageAlignment == 0, 85 "Invalid ObserveProxyEventData size."); 86 87 static_assert(sizeof(ObserveProxyAckEventData) % kPortsMessageAlignment == 0, 88 "Invalid ObserveProxyAckEventData size."); 89 90 static_assert(sizeof(ObserveClosureEventData) % kPortsMessageAlignment == 0, 91 "Invalid ObserveClosureEventData size."); 92 93 static_assert(sizeof(MergePortEventData) % kPortsMessageAlignment == 0, 94 "Invalid MergePortEventData size."); 95 96 static_assert(sizeof(UserMessageReadAckRequestEventData) % 97 kPortsMessageAlignment == 98 0, 99 "Invalid UserMessageReadAckRequestEventData size."); 100 101 static_assert(sizeof(UserMessageReadAckEventData) % kPortsMessageAlignment == 0, 102 "Invalid UserMessageReadAckEventData size."); 103 104 static_assert(sizeof(UpdatePreviousPeerEventData) % kPortsMessageAlignment == 0, 105 "Invalid UpdatePreviousPeerEventData size."); 106 107 } // namespace 108 109 Event::~Event() = default; 110 111 // static 112 ScopedEvent Event::Deserialize(const void* buffer, size_t num_bytes) { 113 if (num_bytes < sizeof(SerializedHeader)) { 114 return nullptr; 115 } 116 117 const auto* header = static_cast<const SerializedHeader*>(buffer); 118 const PortName& port_name = header->port_name; 119 const PortName& from_port = header->from_port; 120 const uint64_t control_sequence_num = header->control_sequence_num; 121 const size_t data_size = num_bytes - sizeof(*header); 122 switch (header->type) { 123 case Type::kUserMessage: 124 return UserMessageEvent::Deserialize( 125 port_name, from_port, control_sequence_num, header + 1, data_size); 126 case Type::kPortAccepted: 127 return PortAcceptedEvent::Deserialize( 128 port_name, from_port, control_sequence_num, header + 1, data_size); 129 case Type::kObserveProxy: 130 return ObserveProxyEvent::Deserialize( 131 port_name, from_port, control_sequence_num, header + 1, data_size); 132 case Type::kObserveProxyAck: 133 return ObserveProxyAckEvent::Deserialize( 134 port_name, from_port, control_sequence_num, header + 1, data_size); 135 case Type::kObserveClosure: 136 return ObserveClosureEvent::Deserialize( 137 port_name, from_port, control_sequence_num, header + 1, data_size); 138 case Type::kMergePort: 139 return MergePortEvent::Deserialize( 140 port_name, from_port, control_sequence_num, header + 1, data_size); 141 case Type::kUserMessageReadAckRequest: 142 return UserMessageReadAckRequestEvent::Deserialize( 143 port_name, from_port, control_sequence_num, header + 1, data_size); 144 case Type::kUserMessageReadAck: 145 return UserMessageReadAckEvent::Deserialize( 146 port_name, from_port, control_sequence_num, header + 1, data_size); 147 case Type::kUpdatePreviousPeer: 148 return UpdatePreviousPeerEvent::Deserialize( 149 port_name, from_port, control_sequence_num, header + 1, data_size); 150 default: 151 DVLOG(2) << "Ingoring unknown port event type: " 152 << static_cast<uint32_t>(header->type); 153 return nullptr; 154 } 155 } 156 157 Event::Event(Type type, const PortName& port_name, const PortName& from_port, 158 uint64_t control_sequence_num) 159 : type_(type), 160 port_name_(port_name), 161 from_port_(from_port), 162 control_sequence_num_(control_sequence_num) {} 163 164 size_t Event::GetSerializedSize() const { 165 return sizeof(SerializedHeader) + GetSerializedDataSize(); 166 } 167 168 void Event::Serialize(void* buffer) const { 169 auto* header = static_cast<SerializedHeader*>(buffer); 170 header->type = type_; 171 header->padding = 0; 172 header->port_name = port_name_; 173 header->from_port = from_port_; 174 header->control_sequence_num = control_sequence_num_; 175 SerializeData(header + 1); 176 } 177 178 ScopedEvent Event::CloneForBroadcast() const { return nullptr; } 179 180 UserMessageEvent::~UserMessageEvent() = default; 181 182 UserMessageEvent::UserMessageEvent(size_t num_ports) 183 : Event(Type::kUserMessage, kInvalidPortName, kInvalidPortName, -1) { 184 ReservePorts(num_ports); 185 } 186 187 void UserMessageEvent::AttachMessage(mozilla::UniquePtr<UserMessage> message) { 188 DCHECK(!message_); 189 message_ = std::move(message); 190 } 191 192 void UserMessageEvent::ReservePorts(size_t num_ports) { 193 port_descriptors_.resize(num_ports); 194 ports_.resize(num_ports); 195 } 196 197 bool UserMessageEvent::NotifyWillBeRoutedExternally() { 198 DCHECK(message_); 199 return message_->WillBeRoutedExternally(*this); 200 } 201 202 // static 203 ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name, 204 const PortName& from_port, 205 uint64_t control_sequence_num, 206 const void* buffer, 207 size_t num_bytes) { 208 if (num_bytes < sizeof(UserMessageEventData)) { 209 return nullptr; 210 } 211 212 const auto* data = static_cast<const UserMessageEventData*>(buffer); 213 mozilla::CheckedInt<size_t> port_data_size = data->num_ports; 214 port_data_size *= sizeof(PortDescriptor) + sizeof(PortName); 215 if (!port_data_size.isValid()) { 216 return nullptr; 217 } 218 219 mozilla::CheckedInt<size_t> total_size = port_data_size.value(); 220 total_size += sizeof(UserMessageEventData); 221 if (!total_size.isValid() || num_bytes < total_size.value()) { 222 return nullptr; 223 } 224 225 auto event = mozilla::WrapUnique(new UserMessageEvent( 226 port_name, from_port, control_sequence_num, data->sequence_num)); 227 event->ReservePorts(data->num_ports); 228 const auto* in_descriptors = 229 reinterpret_cast<const PortDescriptor*>(data + 1); 230 std::copy(in_descriptors, in_descriptors + data->num_ports, 231 event->port_descriptors()); 232 233 const auto* in_names = 234 reinterpret_cast<const PortName*>(in_descriptors + data->num_ports); 235 std::copy(in_names, in_names + data->num_ports, event->ports()); 236 return event; 237 } 238 239 UserMessageEvent::UserMessageEvent(const PortName& port_name, 240 const PortName& from_port, 241 uint64_t control_sequence_num, 242 uint64_t sequence_num) 243 : Event(Type::kUserMessage, port_name, from_port, control_sequence_num), 244 sequence_num_(sequence_num) {} 245 246 size_t UserMessageEvent::GetSizeIfSerialized() const { 247 if (!message_) { 248 return 0; 249 } 250 return message_->GetSizeIfSerialized(); 251 } 252 253 size_t UserMessageEvent::GetSerializedDataSize() const { 254 DCHECK_EQ(ports_.size(), port_descriptors_.size()); 255 mozilla::CheckedInt<size_t> size = sizeof(UserMessageEventData); 256 mozilla::CheckedInt<size_t> ports_size = 257 sizeof(PortDescriptor) + sizeof(PortName); 258 ports_size *= ports_.size(); 259 mozilla::CheckedInt<size_t> combined = size + ports_size; 260 MOZ_RELEASE_ASSERT(combined.isValid()); 261 return combined.value(); 262 } 263 264 void UserMessageEvent::SerializeData(void* buffer) const { 265 DCHECK_EQ(ports_.size(), port_descriptors_.size()); 266 auto* data = static_cast<UserMessageEventData*>(buffer); 267 data->sequence_num = sequence_num_; 268 mozilla::CheckedInt<uint32_t> num_ports{ports_.size()}; 269 DCHECK(num_ports.isValid()); 270 data->num_ports = num_ports.value(); 271 data->padding = 0; 272 273 auto* ports_data = reinterpret_cast<PortDescriptor*>(data + 1); 274 std::copy(port_descriptors_.begin(), port_descriptors_.end(), ports_data); 275 276 auto* port_names_data = 277 reinterpret_cast<PortName*>(ports_data + ports_.size()); 278 std::copy(ports_.begin(), ports_.end(), port_names_data); 279 } 280 281 PortAcceptedEvent::PortAcceptedEvent(const PortName& port_name, 282 const PortName& from_port, 283 uint64_t control_sequence_num) 284 : Event(Type::kPortAccepted, port_name, from_port, control_sequence_num) {} 285 286 PortAcceptedEvent::~PortAcceptedEvent() = default; 287 288 // static 289 ScopedEvent PortAcceptedEvent::Deserialize(const PortName& port_name, 290 const PortName& from_port, 291 uint64_t control_sequence_num, 292 const void* buffer, 293 size_t num_bytes) { 294 return mozilla::MakeUnique<PortAcceptedEvent>(port_name, from_port, 295 control_sequence_num); 296 } 297 298 size_t PortAcceptedEvent::GetSerializedDataSize() const { return 0; } 299 300 void PortAcceptedEvent::SerializeData(void* buffer) const {} 301 302 ObserveProxyEvent::ObserveProxyEvent(const PortName& port_name, 303 const PortName& from_port, 304 uint64_t control_sequence_num, 305 const NodeName& proxy_node_name, 306 const PortName& proxy_port_name, 307 const NodeName& proxy_target_node_name, 308 const PortName& proxy_target_port_name) 309 : Event(Type::kObserveProxy, port_name, from_port, control_sequence_num), 310 proxy_node_name_(proxy_node_name), 311 proxy_port_name_(proxy_port_name), 312 proxy_target_node_name_(proxy_target_node_name), 313 proxy_target_port_name_(proxy_target_port_name) {} 314 315 ObserveProxyEvent::~ObserveProxyEvent() = default; 316 317 // static 318 ScopedEvent ObserveProxyEvent::Deserialize(const PortName& port_name, 319 const PortName& from_port, 320 uint64_t control_sequence_num, 321 const void* buffer, 322 size_t num_bytes) { 323 if (num_bytes < sizeof(ObserveProxyEventData)) { 324 return nullptr; 325 } 326 327 const auto* data = static_cast<const ObserveProxyEventData*>(buffer); 328 return mozilla::MakeUnique<ObserveProxyEvent>( 329 port_name, from_port, control_sequence_num, data->proxy_node_name, 330 data->proxy_port_name, data->proxy_target_node_name, 331 data->proxy_target_port_name); 332 } 333 334 size_t ObserveProxyEvent::GetSerializedDataSize() const { 335 return sizeof(ObserveProxyEventData); 336 } 337 338 void ObserveProxyEvent::SerializeData(void* buffer) const { 339 auto* data = static_cast<ObserveProxyEventData*>(buffer); 340 data->proxy_node_name = proxy_node_name_; 341 data->proxy_port_name = proxy_port_name_; 342 data->proxy_target_node_name = proxy_target_node_name_; 343 data->proxy_target_port_name = proxy_target_port_name_; 344 } 345 346 ScopedEvent ObserveProxyEvent::CloneForBroadcast() const { 347 // Don't broadcast events targeted at specific ports. Otherwise a malicious 348 // node can use this to bypass sender verification. 349 if (port_name() != kInvalidPortName) { 350 return nullptr; 351 } 352 return mozilla::MakeUnique<ObserveProxyEvent>( 353 port_name(), from_port(), control_sequence_num(), proxy_node_name_, 354 proxy_port_name_, proxy_target_node_name_, proxy_target_port_name_); 355 } 356 357 ObserveProxyAckEvent::ObserveProxyAckEvent(const PortName& port_name, 358 const PortName& from_port, 359 uint64_t control_sequence_num, 360 uint64_t last_sequence_num) 361 : Event(Type::kObserveProxyAck, port_name, from_port, control_sequence_num), 362 last_sequence_num_(last_sequence_num) {} 363 364 ObserveProxyAckEvent::~ObserveProxyAckEvent() = default; 365 366 // static 367 ScopedEvent ObserveProxyAckEvent::Deserialize(const PortName& port_name, 368 const PortName& from_port, 369 uint64_t control_sequence_num, 370 const void* buffer, 371 size_t num_bytes) { 372 if (num_bytes < sizeof(ObserveProxyAckEventData)) { 373 return nullptr; 374 } 375 376 const auto* data = static_cast<const ObserveProxyAckEventData*>(buffer); 377 return mozilla::MakeUnique<ObserveProxyAckEvent>( 378 port_name, from_port, control_sequence_num, data->last_sequence_num); 379 } 380 381 size_t ObserveProxyAckEvent::GetSerializedDataSize() const { 382 return sizeof(ObserveProxyAckEventData); 383 } 384 385 void ObserveProxyAckEvent::SerializeData(void* buffer) const { 386 auto* data = static_cast<ObserveProxyAckEventData*>(buffer); 387 data->last_sequence_num = last_sequence_num_; 388 } 389 390 ObserveClosureEvent::ObserveClosureEvent(const PortName& port_name, 391 const PortName& from_port, 392 uint64_t control_sequence_num, 393 uint64_t last_sequence_num) 394 : Event(Type::kObserveClosure, port_name, from_port, control_sequence_num), 395 last_sequence_num_(last_sequence_num) {} 396 397 ObserveClosureEvent::~ObserveClosureEvent() = default; 398 399 // static 400 ScopedEvent ObserveClosureEvent::Deserialize(const PortName& port_name, 401 const PortName& from_port, 402 uint64_t control_sequence_num, 403 const void* buffer, 404 size_t num_bytes) { 405 if (num_bytes < sizeof(ObserveClosureEventData)) { 406 return nullptr; 407 } 408 409 const auto* data = static_cast<const ObserveClosureEventData*>(buffer); 410 return mozilla::MakeUnique<ObserveClosureEvent>( 411 port_name, from_port, control_sequence_num, data->last_sequence_num); 412 } 413 414 size_t ObserveClosureEvent::GetSerializedDataSize() const { 415 return sizeof(ObserveClosureEventData); 416 } 417 418 void ObserveClosureEvent::SerializeData(void* buffer) const { 419 auto* data = static_cast<ObserveClosureEventData*>(buffer); 420 data->last_sequence_num = last_sequence_num_; 421 } 422 423 MergePortEvent::MergePortEvent(const PortName& port_name, 424 const PortName& from_port, 425 uint64_t control_sequence_num, 426 const PortName& new_port_name, 427 const PortDescriptor& new_port_descriptor) 428 : Event(Type::kMergePort, port_name, from_port, control_sequence_num), 429 new_port_name_(new_port_name), 430 new_port_descriptor_(new_port_descriptor) {} 431 432 MergePortEvent::~MergePortEvent() = default; 433 434 // static 435 ScopedEvent MergePortEvent::Deserialize(const PortName& port_name, 436 const PortName& from_port, 437 uint64_t control_sequence_num, 438 const void* buffer, size_t num_bytes) { 439 if (num_bytes < sizeof(MergePortEventData)) { 440 return nullptr; 441 } 442 443 const auto* data = static_cast<const MergePortEventData*>(buffer); 444 return mozilla::MakeUnique<MergePortEvent>( 445 port_name, from_port, control_sequence_num, data->new_port_name, 446 data->new_port_descriptor); 447 } 448 449 size_t MergePortEvent::GetSerializedDataSize() const { 450 return sizeof(MergePortEventData); 451 } 452 453 void MergePortEvent::SerializeData(void* buffer) const { 454 auto* data = static_cast<MergePortEventData*>(buffer); 455 data->new_port_name = new_port_name_; 456 data->new_port_descriptor = new_port_descriptor_; 457 } 458 459 UserMessageReadAckRequestEvent::UserMessageReadAckRequestEvent( 460 const PortName& port_name, const PortName& from_port, 461 uint64_t control_sequence_num, uint64_t sequence_num_to_acknowledge) 462 : Event(Type::kUserMessageReadAckRequest, port_name, from_port, 463 control_sequence_num), 464 sequence_num_to_acknowledge_(sequence_num_to_acknowledge) {} 465 466 UserMessageReadAckRequestEvent::~UserMessageReadAckRequestEvent() = default; 467 468 // static 469 ScopedEvent UserMessageReadAckRequestEvent::Deserialize( 470 const PortName& port_name, const PortName& from_port, 471 uint64_t control_sequence_num, const void* buffer, size_t num_bytes) { 472 if (num_bytes < sizeof(UserMessageReadAckRequestEventData)) { 473 return nullptr; 474 } 475 476 const auto* data = 477 static_cast<const UserMessageReadAckRequestEventData*>(buffer); 478 return mozilla::MakeUnique<UserMessageReadAckRequestEvent>( 479 port_name, from_port, control_sequence_num, 480 data->sequence_num_to_acknowledge); 481 } 482 483 size_t UserMessageReadAckRequestEvent::GetSerializedDataSize() const { 484 return sizeof(UserMessageReadAckRequestEventData); 485 } 486 487 void UserMessageReadAckRequestEvent::SerializeData(void* buffer) const { 488 auto* data = static_cast<UserMessageReadAckRequestEventData*>(buffer); 489 data->sequence_num_to_acknowledge = sequence_num_to_acknowledge_; 490 } 491 492 UserMessageReadAckEvent::UserMessageReadAckEvent( 493 const PortName& port_name, const PortName& from_port, 494 uint64_t control_sequence_num, uint64_t sequence_num_acknowledged) 495 : Event(Type::kUserMessageReadAck, port_name, from_port, 496 control_sequence_num), 497 sequence_num_acknowledged_(sequence_num_acknowledged) {} 498 499 UserMessageReadAckEvent::~UserMessageReadAckEvent() = default; 500 501 // static 502 ScopedEvent UserMessageReadAckEvent::Deserialize(const PortName& port_name, 503 const PortName& from_port, 504 uint64_t control_sequence_num, 505 const void* buffer, 506 size_t num_bytes) { 507 if (num_bytes < sizeof(UserMessageReadAckEventData)) { 508 return nullptr; 509 } 510 511 const auto* data = static_cast<const UserMessageReadAckEventData*>(buffer); 512 return mozilla::MakeUnique<UserMessageReadAckEvent>( 513 port_name, from_port, control_sequence_num, 514 data->sequence_num_acknowledged); 515 } 516 517 size_t UserMessageReadAckEvent::GetSerializedDataSize() const { 518 return sizeof(UserMessageReadAckEventData); 519 } 520 521 void UserMessageReadAckEvent::SerializeData(void* buffer) const { 522 auto* data = static_cast<UserMessageReadAckEventData*>(buffer); 523 data->sequence_num_acknowledged = sequence_num_acknowledged_; 524 } 525 526 UpdatePreviousPeerEvent::UpdatePreviousPeerEvent(const PortName& port_name, 527 const PortName& from_port, 528 uint64_t control_sequence_num, 529 const NodeName& new_node_name, 530 const PortName& new_port_name) 531 : Event(Type::kUpdatePreviousPeer, port_name, from_port, 532 control_sequence_num), 533 new_node_name_(new_node_name), 534 new_port_name_(new_port_name) {} 535 536 UpdatePreviousPeerEvent::~UpdatePreviousPeerEvent() = default; 537 538 // static 539 ScopedEvent UpdatePreviousPeerEvent::Deserialize(const PortName& port_name, 540 const PortName& from_port, 541 uint64_t control_sequence_num, 542 const void* buffer, 543 size_t num_bytes) { 544 if (num_bytes < sizeof(UpdatePreviousPeerEventData)) return nullptr; 545 const auto* data = static_cast<const UpdatePreviousPeerEventData*>(buffer); 546 return mozilla::MakeUnique<UpdatePreviousPeerEvent>( 547 port_name, from_port, control_sequence_num, data->new_node_name, 548 data->new_port_name); 549 } 550 551 size_t UpdatePreviousPeerEvent::GetSerializedDataSize() const { 552 return sizeof(UpdatePreviousPeerEventData); 553 } 554 555 void UpdatePreviousPeerEvent::SerializeData(void* buffer) const { 556 auto* data = static_cast<UpdatePreviousPeerEventData*>(buffer); 557 data->new_node_name = new_node_name_; 558 data->new_port_name = new_port_name_; 559 } 560 561 } // namespace ports 562 } // namespace core 563 } // namespace mojo