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

Commit ce90c702 authored by Mehmet Murat Sevim's avatar Mehmet Murat Sevim Committed by Automerger Merge Worker
Browse files

Merge "Revert "Fix an OOB write bug in attp_build_value_cmd"" into tm-dev am:...

Merge "Revert "Fix an OOB write bug in attp_build_value_cmd"" into tm-dev am: 24ed2f4e am: b549dd54 am: b45abcf0 am: 140d750d am: 6626cd69

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/25558746



Change-Id: If449cfab0c5ff4afe415eccd8a661fdd38adff13
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents cc1b96c0 6626cd69
Loading
Loading
Loading
Loading
+11 −44
Original line number Diff line number Diff line
@@ -286,79 +286,46 @@ static BT_HDR* attp_build_opcode_cmd(uint8_t op_code) {
static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
                                    uint16_t handle, uint16_t offset,
                                    uint16_t len, uint8_t* p_data) {
  uint8_t *p, *pp, *p_pair_len;
  size_t pair_len;
  size_t size_now = 1;

  #define CHECK_SIZE() do {                      \
    if (size_now > payload_size) {               \
      LOG(ERROR) << "payload size too small";    \
      osi_free(p_buf);                           \
      return nullptr;                            \
    }                                            \
  } while (false)

  uint8_t *p, *pp, pair_len, *p_pair_len;
  BT_HDR* p_buf =
      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);

  p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;

  CHECK_SIZE();
  UINT8_TO_STREAM(p, op_code);
  p_buf->offset = L2CAP_MIN_OFFSET;
  p_buf->len = 1;

  if (op_code == GATT_RSP_READ_BY_TYPE) {
    p_pair_len = p;
    pair_len = len + 2;
    size_now += 1;
    CHECK_SIZE();
    // this field will be backfilled in the end of this function
    UINT8_TO_STREAM(p, pair_len);
    p_buf->len += 1;
  }

  if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) {
    size_now += 2;
    CHECK_SIZE();
    UINT16_TO_STREAM(p, handle);
    p_buf->len += 2;
  }

  if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
    size_now += 2;
    CHECK_SIZE();
    UINT16_TO_STREAM(p, offset);
    p_buf->len += 2;
  }

  if (len > 0 && p_data != NULL && payload_size > size_now) {
  if (len > 0 && p_data != NULL) {
    /* ensure data not exceed MTU size */
    if (payload_size - size_now < len) {
      len = payload_size - size_now;
    if (payload_size - p_buf->len < len) {
      len = payload_size - p_buf->len;
      /* update handle value pair length */
      if (op_code == GATT_RSP_READ_BY_TYPE) {
        pair_len = (len + 2);
      }
      if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);

      LOG(WARNING) << StringPrintf(
          "attribute value too long, to be truncated to %d", len);
    }

    size_now += len;
    CHECK_SIZE();
    ARRAY_TO_STREAM(p, p_data, len);
    p_buf->len += len;
  }

  // backfill pair len field
  if (op_code == GATT_RSP_READ_BY_TYPE) {
    if (pair_len > UINT8_MAX) {
      LOG(ERROR) << "pair_len greater than" << UINT8_MAX;
      osi_free(p_buf);
      return nullptr;
    }

    *p_pair_len = (uint8_t) pair_len;
  }

  #undef CHECK_SIZE

  p_buf->len = (uint16_t) size_now;
  return p_buf;
}