tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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