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

Commit cf135182 authored by jruthe's avatar jruthe
Browse files

test_vendor: L2cap Assemble additional error check

Assemble now properly checks the proposed length of a segmented SDU that
is given in the first packet of any segmented SDU in accordance with
Bluetooth Core Specification Version 4.2 Volume 3 Part A 3.3.2

Test: Passed in test/l2cap_test.cc
Change-Id: Idbbd1c014bac8928affab581118f73a7d9126824
parent c0a51acc
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ std::unique_ptr<L2capPacket> L2capPacket::assemble(
  std::unique_ptr<L2capPacket> built_l2cap_packet(new L2capPacket());
  uint16_t l2cap_payload_length = 0;
  uint16_t first_packet_channel_id = 0;
  uint16_t total_expected_l2cap_length;
  uint8_t txseq_start;

  if (sdu_packets.size() == 0) {
@@ -85,29 +86,39 @@ std::unique_ptr<L2capPacket> L2capPacket::assemble(
    // Meanwhile all segments in between the start and end must have the bits
    // set to 11b.
    uint16_t starting_index;
    uint16_t total_expected_l2cap_length;
    uint8_t txseq = controls & kSduTxSeqBits;
    if (sdu_packets.size() == 1 && !check_if_only_sdu(continuation_bits)) {
      return nullptr;
    } else if (sdu_packets.size() > 1 && i == 0 &&
    }
    if (sdu_packets.size() > 1 && i == 0 &&
        !check_if_starting_sdu(continuation_bits)) {
      return nullptr;
    } else if (i != 0 && check_if_starting_sdu(continuation_bits)) {
    }
    if (i != 0 && check_if_starting_sdu(continuation_bits)) {
      return nullptr;
    } else if (txseq != (txseq_start + (static_cast<uint8_t>(i) << 1))) {
    }
    if (txseq != (txseq_start + (static_cast<uint8_t>(i) << 1))) {
      return nullptr;
    } else if (sdu_packets.size() > 1 && i == sdu_packets.size() - 1 &&
    }
    if (sdu_packets.size() > 1 && i == sdu_packets.size() - 1 &&
        !check_if_ending_sdu(continuation_bits)) {
      return nullptr;
    } else if (check_if_starting_sdu(continuation_bits)) {
    }

    // Subtract the control and fcs from every SDU payload length.
    l2cap_payload_length += (payload_length - 4);

    if (check_if_starting_sdu(continuation_bits)) {
      starting_index = kSduFirstHeaderLength;
      total_expected_l2cap_length = sdu_packets[i].get_total_l2cap_length();

      // Subtract the additional two bytes from the first packet of a segmented
      // SDU.
      l2cap_payload_length -= 2;
    } else {
      starting_index = kSduStandardHeaderLength;
    }

    l2cap_payload_length += (payload_length - 2);

    auto payload_begin = sdu_packets[i].get_payload_begin(starting_index);
    auto payload_end = sdu_packets[i].get_payload_end();

@@ -115,6 +126,11 @@ std::unique_ptr<L2capPacket> L2capPacket::assemble(
        built_l2cap_packet->l2cap_packet_.end(), payload_begin, payload_end);
  }

  if (l2cap_payload_length != total_expected_l2cap_length &&
      sdu_packets.size() > 1) {
    return nullptr;
  }

  built_l2cap_packet->l2cap_packet_[0] = l2cap_payload_length & 0xff;
  built_l2cap_packet->l2cap_packet_[1] = (l2cap_payload_length & 0xff00) >> 8;
  built_l2cap_packet->l2cap_packet_[2] = first_packet_channel_id & 0xff;