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

Commit 6626cd69 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

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



Change-Id: Ib337d2bb40b4d11dce581df03ade02f72b1c161d
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 1c904a99 140d750d
Loading
Loading
Loading
Loading
+11 −44
Original line number Diff line number Diff line
@@ -287,79 +287,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;
}