Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64363622 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "gd: l2cap Skip undefined options when parsing" am: 67398b00

Change-Id: I94125bb60a2ff6dce6cb8e337f70615b9ee1b344
parents 7c846820 67398b00
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -62,6 +62,68 @@ DEFINE_AND_INSTANTIATE_GroupFrameReflectionTest(g_frame);
std::vector<uint8_t> config_mtu_request = {0x04, 0x05, 0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x02, 0xa0, 0x02};
DEFINE_AND_INSTANTIATE_ConfigurationRequestReflectionTest(config_mtu_request);

std::vector<uint8_t> config_request_one_defined_option = {0x04, 0x05, 0x08, 0x00, 0x41, 0x00,
                                                          0x00, 0x00, 0x01, 0x02, 0x12, 0x34};
std::vector<uint8_t> config_request_two_defined_options = {0x04, 0x05, 0x0c, 0x00, 0x41, 0x00, 0x00, 0x00,
                                                           0x01, 0x02, 0x12, 0x34, 0x02, 0x02, 0x56, 0x78};
std::vector<uint8_t> config_request_two_undefined_options = {0x04, 0x05, 0x0e, 0x00, 0x41, 0x00, 0x00, 0x00, 0x7f,
                                                             0x02, 0x01, 0x00, 0x7e, 0x04, 0x11, 0x11, 0x00, 0x00};
std::vector<uint8_t> config_request_hint_one_defined_option = {0x04, 0x05, 0x08, 0x00, 0x41, 0x00,
                                                               0x00, 0x00, 0x81, 0x02, 0x12, 0x34};
std::vector<uint8_t> config_request_hint_two_undefined_options = {0x04, 0x05, 0x0c, 0x00, 0x41, 0x00, 0x00, 0x00,
                                                                  0x90, 0x02, 0x01, 0x00, 0x91, 0x02, 0x11, 0x11};
TEST(L2capPacketsTest, testConfigRequestOptions) {
  {
    std::shared_ptr<std::vector<uint8_t>> view_bytes =
        std::make_shared<std::vector<uint8_t>>(config_request_one_defined_option);

    PacketView<kLittleEndian> packet_bytes_view(view_bytes);
    auto view = ConfigurationRequestView::Create(ControlView::Create(packet_bytes_view));
    ASSERT_TRUE(view.IsValid());
    ASSERT_EQ(1, view.GetConfig().size());
  }

  {
    std::shared_ptr<std::vector<uint8_t>> view_bytes =
        std::make_shared<std::vector<uint8_t>>(config_request_two_defined_options);

    PacketView<kLittleEndian> packet_bytes_view(view_bytes);
    auto view = ConfigurationRequestView::Create(ControlView::Create(packet_bytes_view));
    ASSERT_TRUE(view.IsValid());
    ASSERT_EQ(2, view.GetConfig().size());
  }

  {
    std::shared_ptr<std::vector<uint8_t>> view_bytes =
        std::make_shared<std::vector<uint8_t>>(config_request_two_undefined_options);

    PacketView<kLittleEndian> packet_bytes_view(view_bytes);
    auto view = ConfigurationRequestView::Create(ControlView::Create(packet_bytes_view));
    ASSERT_TRUE(view.IsValid());
    ASSERT_EQ(2, view.GetConfig().size());
  }

  {
    std::shared_ptr<std::vector<uint8_t>> view_bytes =
        std::make_shared<std::vector<uint8_t>>(config_request_hint_one_defined_option);

    PacketView<kLittleEndian> packet_bytes_view(view_bytes);
    auto view = ConfigurationRequestView::Create(ControlView::Create(packet_bytes_view));
    ASSERT_TRUE(view.IsValid());
    ASSERT_EQ(1, view.GetConfig().size());
  }

  {
    std::shared_ptr<std::vector<uint8_t>> view_bytes =
        std::make_shared<std::vector<uint8_t>>(config_request_hint_two_undefined_options);

    PacketView<kLittleEndian> packet_bytes_view(view_bytes);
    auto view = ConfigurationRequestView::Create(ControlView::Create(packet_bytes_view));
    ASSERT_TRUE(view.IsValid());
    ASSERT_EQ(2, view.GetConfig().size());
  }
}

DEFINE_ConfigurationRequestReflectionFuzzTest();

TEST(L2capFuzzRegressions, ConfigurationRequestFuzz_5691566077247488) {
+8 −8
Original line number Diff line number Diff line
@@ -309,15 +309,15 @@ enum ConfigurationOptionIsHint : 1 {
struct ConfigurationOption {
  type : ConfigurationOptionType,
  is_hint : ConfigurationOptionIsHint,
  length : 8,
  _size_(_body_) : 8,
  _body_,
}

struct MtuConfigurationOption : ConfigurationOption (type = MTU, length = 2) {
struct MtuConfigurationOption : ConfigurationOption (type = MTU) {
  mtu : 16,
}

struct FlushTimeoutConfigurationOption : ConfigurationOption (type = FLUSH_TIMEOUT, length = 2) {
struct FlushTimeoutConfigurationOption : ConfigurationOption (type = FLUSH_TIMEOUT) {
  flush_timeout : 16,
}

@@ -327,7 +327,7 @@ enum QosServiceType : 8 {
  GUARANTEED = 0x02,
}

struct QualityOfServiceConfigurationOption : ConfigurationOption (type = QUALITY_OF_SERVICE, length = 22) {
struct QualityOfServiceConfigurationOption : ConfigurationOption (type = QUALITY_OF_SERVICE) {
  _reserved_ : 8, // Flags
  service_type : QosServiceType,
  token_rate : 32,         // 0 = ignore, 0xffffffff = max available
@@ -346,7 +346,7 @@ enum RetransmissionAndFlowControlModeOption : 8 {
}


struct RetransmissionAndFlowControlConfigurationOption : ConfigurationOption (type = RETRANSMISSION_AND_FLOW_CONTROL, length = 9) {
struct RetransmissionAndFlowControlConfigurationOption : ConfigurationOption (type = RETRANSMISSION_AND_FLOW_CONTROL) {
  mode : RetransmissionAndFlowControlModeOption,
  tx_window_size : 8, // 1-32 for Flow Control and Retransmission, 1-63 for Enhanced
  max_transmit : 8,
@@ -360,12 +360,12 @@ enum FcsType : 8 {
  DEFAULT = 1,  // 16-bit FCS
}

struct FrameCheckSequenceOption : ConfigurationOption (type = FRAME_CHECK_SEQUENCE, length = 1) {
struct FrameCheckSequenceOption : ConfigurationOption (type = FRAME_CHECK_SEQUENCE) {
  fcs_type : FcsType,
}


struct ExtendedFlowSpecificationOption : ConfigurationOption (type = EXTENDED_FLOW_SPECIFICATION, length = 16) {
struct ExtendedFlowSpecificationOption : ConfigurationOption (type = EXTENDED_FLOW_SPECIFICATION) {
  identifier : 8, // Default 0x01, must be 0x01 for Extended Flow-Best-Effort
  service_type : QosServiceType,
  maximum_sdu_size : 16, // Octets
@@ -374,7 +374,7 @@ struct ExtendedFlowSpecificationOption : ConfigurationOption (type = EXTENDED_FL
  flush_timeout : 32, // in microseconds 0x0 = no retransmissions 0xFFFFFFFF = never flushed
}

struct ExtendedWindowSizeOption : ConfigurationOption (type = EXTENDED_WINDOW_SIZE, length = 2) {
struct ExtendedWindowSizeOption : ConfigurationOption (type = EXTENDED_WINDOW_SIZE) {
  max_window_size : 16, // 0x0000 = Valid for streaming, 0x0001-0x3FFF Valid for Enhanced Retransmission
}

+12 −1
Original line number Diff line number Diff line
@@ -20,13 +20,24 @@ const std::string BodyField::kFieldType = "BodyField";

BodyField::BodyField(ParseLocation loc) : PacketField("body", loc) {}

void BodyField::SetSizeField(const SizeField* size_field) {
  if (size_field_ != nullptr) {
    ERROR(this, size_field_, size_field) << "The size field for the body has already been assigned.";
  }
  size_field_ = size_field;
}

const std::string& BodyField::GetFieldType() const {
  return BodyField::kFieldType;
}

Size BodyField::GetSize() const {
  if (size_field_ == nullptr) {
    return Size(0);
  }
  std::string dynamic_size = "(" + size_field_->GetName() + " * 8)";
  return dynamic_size;
}

std::string BodyField::GetDataType() const {
  ERROR(this) << "No need to know the type of a body field.";
+5 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ class BodyField : public PacketField {

  virtual const std::string& GetFieldType() const override;

  void SetSizeField(const SizeField* size_field);

  virtual Size GetSize() const override;

  virtual std::string GetDataType() const override;
@@ -47,4 +49,7 @@ class BodyField : public PacketField {
  virtual void GenInserter(std::ostream&) const override;

  virtual void GenValidator(std::ostream&) const override;

  // Body fields can only be dynamically sized.
  const SizeField* size_field_{nullptr};
};
+4 −4
Original line number Diff line number Diff line
@@ -89,15 +89,15 @@ Size VectorField::GetStructSize() const {

  // size_field_ is of type SIZE
  if (size_field_->GetFieldType() == SizeField::kFieldType) {
    std::string ret = "(static_cast<size_t>(" + size_field_->GetName() + "_extracted) * 8)";
    std::string ret = "(static_cast<size_t>(to_fill->" + size_field_->GetName() + "_extracted_) * 8)";
    if (!size_modifier_.empty()) ret += "-" + size_modifier_;
    return ret;
  }

  // size_field_ is of type COUNT and elements have a fixed size
  if (!element_size_.empty() && !element_size_.has_dynamic()) {
    return "(static_cast<size_t>(" + size_field_->GetName() + "_extracted) * " + std::to_string(element_size_.bits()) +
           ")";
    return "(static_cast<size_t>(to_fill->" + size_field_->GetName() + "_extracted_) * " +
           std::to_string(element_size_.bits()) + ")";
  }

  return Size();
@@ -112,7 +112,7 @@ void VectorField::GenExtractor(std::ostream& s, int num_leading_bits, bool for_s
  if (size_field_ != nullptr && size_field_->GetFieldType() == CountField::kFieldType) {
    s << "size_t " << element_field_->GetName() << "_count = ";
    if (for_struct) {
      s << size_field_->GetName() << "_extracted;";
      s << "to_fill->" << size_field_->GetName() << "_extracted_;";
    } else {
      s << "Get" << util::UnderscoreToCamelCase(size_field_->GetName()) << "();";
    }
Loading