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

Commit 43ebbf55 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: a5ba99a1

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



Change-Id: Icbe8f66cb2ac1a97d17d4143df7147501af95cf4
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 3dbc6fb1 a5ba99a1
Loading
Loading
Loading
Loading
+11 −44
Original line number Original line 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,
static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
                                    uint16_t handle, uint16_t offset,
                                    uint16_t handle, uint16_t offset,
                                    uint16_t len, uint8_t* p_data) {
                                    uint16_t len, uint8_t* p_data) {
  uint8_t *p, *pp, *p_pair_len;
  uint8_t *p, *pp, pair_len, *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)

  BT_HDR* p_buf =
  BT_HDR* p_buf =
      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
      (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);


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

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


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

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


  if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
  if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
    size_now += 2;
    CHECK_SIZE();
    UINT16_TO_STREAM(p, offset);
    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 */
    /* ensure data not exceed MTU size */
    if (payload_size - size_now < len) {
    if (payload_size - p_buf->len < len) {
      len = payload_size - size_now;
      len = payload_size - p_buf->len;
      /* update handle value pair length */
      /* update handle value pair length */
      if (op_code == GATT_RSP_READ_BY_TYPE) {
      if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
        pair_len = (len + 2);
      }


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


    size_now += len;
    CHECK_SIZE();
    ARRAY_TO_STREAM(p, p_data, len);
    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;
  return p_buf;
}
}