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

Commit b45abcf0 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

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



Change-Id: Id353c27adee0769ff70c3c48753e5f9ddc232837
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 977bf855 b549dd54
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;
}