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

Commit 8e1f7414 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/22948134',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/22948134', 'googleplex-android-review.googlesource.com/25503067', 'googleplex-android-review.googlesource.com/25494184'] into security-aosp-udc-release.

Change-Id: I896d7ddea13a7a81007ed89495021c61be809d18
parents 92cc886f bd2d00da
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@


#define LOG_TAG "bt_btif_gatt"
#define LOG_TAG "bt_btif_gatt"


#include <algorithm>

#include "btif_gatt_util.h"
#include "btif_gatt_util.h"


#include <errno.h>
#include <errno.h>
@@ -52,9 +54,9 @@ using bluetooth::Uuid;
void btif_to_bta_response(tGATTS_RSP* p_dest, btgatt_response_t* p_src) {
void btif_to_bta_response(tGATTS_RSP* p_dest, btgatt_response_t* p_src) {
  p_dest->attr_value.auth_req = p_src->attr_value.auth_req;
  p_dest->attr_value.auth_req = p_src->attr_value.auth_req;
  p_dest->attr_value.handle = p_src->attr_value.handle;
  p_dest->attr_value.handle = p_src->attr_value.handle;
  p_dest->attr_value.len = p_src->attr_value.len;
  p_dest->attr_value.len = std::min<uint16_t>(p_src->attr_value.len, GATT_MAX_ATTR_LEN);
  p_dest->attr_value.offset = p_src->attr_value.offset;
  p_dest->attr_value.offset = p_src->attr_value.offset;
  memcpy(p_dest->attr_value.value, p_src->attr_value.value, GATT_MAX_ATTR_LEN);
  memcpy(p_dest->attr_value.value, p_src->attr_value.value, p_dest->attr_value.len);
}
}


/*******************************************************************************
/*******************************************************************************
+51 −12
Original line number Original line Diff line number Diff line
@@ -165,7 +165,13 @@ static BT_HDR* attp_build_read_by_type_value_cmd(
    uint16_t payload_size, tGATT_FIND_TYPE_VALUE* p_value_type) {
    uint16_t payload_size, tGATT_FIND_TYPE_VALUE* p_value_type) {
  uint8_t* p;
  uint8_t* p;
  uint16_t len = p_value_type->value_len;
  uint16_t len = p_value_type->value_len;
  BT_HDR* p_buf =
  BT_HDR* p_buf = nullptr;

  if (payload_size < 5) {
    return nullptr;
  }

  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 = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
  p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
@@ -281,46 +287,79 @@ 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, pair_len, *p_pair_len;
  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)

  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;
    UINT8_TO_STREAM(p, pair_len);
    size_now += 1;
    p_buf->len += 1;
    CHECK_SIZE();
    // 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) {
  if (len > 0 && p_data != NULL && payload_size > size_now) {
    /* ensure data not exceed MTU size */
    /* ensure data not exceed MTU size */
    if (payload_size - p_buf->len < len) {
    if (payload_size - size_now < len) {
      len = payload_size - p_buf->len;
      len = payload_size - size_now;
      /* update handle value pair length */
      /* update handle value pair length */
      if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
      if (op_code == GATT_RSP_READ_BY_TYPE) {
        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;
}
}