Revert "Fix an OOB write bug in attp_build_value_cmd" This reverts commit a0d4425c3964f99f589d449deed2f1bbe520218c. Reason for revert: LE Device name is incorrect after the change. See b/315127634 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6dbe94fe556ef67f3bbb7d7bb2da3320d68619df) Merged-In: I93906e7ab768b4015fe3491e171fdb0ec8cf3077 Change-Id: I93906e7ab768b4015fe3491e171fdb0ec8cf3077
diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc index f055fb8..29ceec2 100644 --- a/system/stack/gatt/att_protocol.cc +++ b/system/stack/gatt/att_protocol.cc
@@ -286,79 +286,46 @@ 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; }