DO NOT MERGE -- Merge PPRL.190405.003 into master
Bug: 130175407
Change-Id: I0d4cfc3362819a2d14e1247d3ffd76b5a32f2524
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
index 142641e..61a6e37 100644
--- a/src/nfc/include/tags_defs.h
+++ b/src/nfc/include/tags_defs.h
@@ -537,6 +537,8 @@
#define I93_INFO_FLAG_AFI 0x02
/* VICC memory size field is present */
#define I93_INFO_FLAG_MEM_SIZE 0x04
+/* 16bit num of blocks info length */
+#define I93_INFO_16BIT_NUM_BLOCK_LEN 0x02
/* IC reference field is present */
#define I93_INFO_FLAG_IC_REF 0x08
/* Memory coded in 2 bytes address */
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index 1e62d34..d390ab0 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -22,6 +22,7 @@
* mode.
*
******************************************************************************/
+#include <log/log.h>
#include <string.h>
#include <android-base/stringprintf.h>
@@ -206,36 +207,64 @@
** Returns FALSE if retrying with protocol extension flag
**
*******************************************************************************/
-bool rw_i93_process_ext_sys_info(uint8_t* p_data) {
+bool rw_i93_process_ext_sys_info(uint8_t* p_data, uint16_t length) {
uint8_t* p = p_data;
tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
DLOG_IF(INFO, nfc_debug_enabled) << __func__;
+ if (length < (I93_UID_BYTE_LEN + 1)) {
+ android_errorWriteLog(0x534e4554, "122316913");
+ return false;
+ }
+
STREAM_TO_UINT8(p_i93->info_flags, p);
+ length--;
p_uid = uid;
STREAM_TO_ARRAY8(p_uid, p);
+ length -= I93_UID_BYTE_LEN;
if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
+ if (length < 1) {
+ android_errorWriteLog(0x534e4554, "122316913");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->dsfid, p);
+ length--;
}
if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
+ if (length < 1) {
+ android_errorWriteLog(0x534e4554, "122316913");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->afi, p);
+ length--;
}
if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
+ if (length < 3) {
+ android_errorWriteLog(0x534e4554, "122316913");
+ return false;
+ }
STREAM_TO_UINT16(p_i93->num_block, p);
+ length -= I93_INFO_16BIT_NUM_BLOCK_LEN;
/* it is one less than actual number of bytes */
p_i93->num_block += 1;
STREAM_TO_UINT8(p_i93->block_size, p);
+ length--;
/* it is one less than actual number of blocks */
p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
}
if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
+ if (length < 1) {
+ android_errorWriteLog(0x534e4554, "122316913");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->ic_reference, p);
+ length--;
/* clear existing UID to set product version */
p_i93->uid[0] = 0x00;
@@ -262,38 +291,65 @@
** Returns FALSE if retrying with protocol extension flag
**
*******************************************************************************/
-bool rw_i93_process_sys_info(uint8_t* p_data) {
+bool rw_i93_process_sys_info(uint8_t* p_data, uint16_t length) {
uint8_t* p = p_data;
tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
DLOG_IF(INFO, nfc_debug_enabled) << __func__;
+ if (length < (I93_UID_BYTE_LEN + 1)) {
+ android_errorWriteLog(0x534e4554, "121259048");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->info_flags, p);
+ length--;
p_uid = uid;
STREAM_TO_ARRAY8(p_uid, p);
+ length -= I93_UID_BYTE_LEN;
if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "121259048");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->dsfid, p);
+ length--;
}
if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "121259048");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->afi, p);
+ length--;
}
if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
- if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+ bool block_16_bit = p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK;
+ if (block_16_bit && length > 2) {
STREAM_TO_UINT16(p_i93->num_block, p);
- } else {
+ length -= 2;
+ } else if (!block_16_bit && length > 1) {
STREAM_TO_UINT8(p_i93->num_block, p);
+ length--;
+ } else {
+ android_errorWriteLog(0x534e4554, "121259048");
+ return false;
}
/* it is one less than actual number of bytes */
p_i93->num_block += 1;
STREAM_TO_UINT8(p_i93->block_size, p);
+ length--;
/* it is one less than actual number of blocks */
p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
}
if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "121259048");
+ return false;
+ }
STREAM_TO_UINT8(p_i93->ic_reference, p);
/* clear existing UID to set product version */
@@ -494,7 +550,7 @@
case I93_CMD_GET_SYS_INFO:
- if (rw_i93_process_sys_info(p)) {
+ if (rw_i93_process_sys_info(p, length)) {
rw_data.i93_sys_info.status = NFC_STATUS_OK;
rw_data.i93_sys_info.info_flags = p_i93->info_flags;
rw_data.i93_sys_info.dsfid = p_i93->dsfid;
@@ -515,7 +571,7 @@
case I93_CMD_EXT_GET_SYS_INFO:
- if (rw_i93_process_ext_sys_info(p)) {
+ if (rw_i93_process_ext_sys_info(p, length)) {
rw_data.i93_sys_info.status = NFC_STATUS_OK;
rw_data.i93_sys_info.info_flags = p_i93->info_flags;
rw_data.i93_sys_info.dsfid = p_i93->dsfid;
@@ -1602,6 +1658,11 @@
"sub_state:%s (0x%x)",
rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "121260197");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
STREAM_TO_UINT8(flags, p);
length--;
@@ -1621,6 +1682,11 @@
switch (p_i93->sub_state) {
case RW_I93_SUBSTATE_WAIT_UID:
+ if (length < (I93_UID_BYTE_LEN + 1)) {
+ android_errorWriteLog(0x534e4554, "121260197");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
STREAM_TO_UINT8(u8, p); /* DSFID */
p_uid = p_i93->uid;
STREAM_TO_ARRAY8(p_uid, p);
@@ -1646,7 +1712,7 @@
p_i93->block_size = 0;
p_i93->num_block = 0;
- if (!rw_i93_process_sys_info(p)) {
+ if (!rw_i93_process_sys_info(p, length)) {
/* retrying with protocol extension flag */
break;
}
@@ -1980,6 +2046,12 @@
DLOG_IF(INFO, nfc_debug_enabled) << __func__;
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "122035770");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
+
STREAM_TO_UINT8(flags, p);
length--;
@@ -2078,6 +2150,12 @@
"sub_state:%s (0x%x)",
rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
+ if (length == 0 || p_i93->block_size > I93_MAX_BLOCK_LENGH) {
+ android_errorWriteLog(0x534e4554, "122320256");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
+
STREAM_TO_UINT8(flags, p);
length--;
@@ -2102,6 +2180,12 @@
/* get offset of length field */
length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
+ if (length < length_offset) {
+ android_errorWriteLog(0x534e4554, "122320256");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
+
/* set length to zero */
*(p + length_offset) = 0x00;
@@ -2115,6 +2199,11 @@
/* write the first part of NDEF in the same block */
for (; xx < p_i93->block_size; xx++) {
+ if (xx > length || p_i93->rw_length > p_i93->ndef_length) {
+ android_errorWriteLog(0x534e4554, "122320256");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
if (p_i93->rw_length < p_i93->ndef_length) {
*(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
} else {
@@ -2261,6 +2350,12 @@
/* update length field within the read block */
for (xx = length_offset; xx < p_i93->block_size; xx++) {
+ if (xx > length) {
+ android_errorWriteLog(0x534e4554, "122320256");
+ rw_i93_handle_error(NFC_STATUS_FAILED);
+ return;
+ }
+
if (p_i93->rw_length == 3)
*(p + xx) = 0xFF;
else if (p_i93->rw_length == 2)
@@ -2372,7 +2467,7 @@
p_i93->block_size = 0;
p_i93->num_block = 0;
- if (!rw_i93_process_sys_info(p)) {
+ if (!rw_i93_process_sys_info(p, length)) {
/* retrying with protocol extension flag */
break;
}
diff --git a/src/nfc/tags/rw_t3t.cc b/src/nfc/tags/rw_t3t.cc
index 1341a81..67da41a 100644
--- a/src/nfc/tags/rw_t3t.cc
+++ b/src/nfc/tags/rw_t3t.cc
@@ -1502,10 +1502,11 @@
T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nfc_status = NFC_STATUS_FAILED;
GKI_freebuf(p_msg_rsp);
- } else {
+ } else if (p_msg_rsp->len >= T3T_MSG_RSP_OFFSET_CHECK_DATA &&
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] > 0) {
/* Notify app of NDEF segment received */
- rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
- 16; /* Number of bytes received, according to header */
+ /* Number of bytes received, according to header */
+ rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16;
p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
p_msg_rsp->offset +=
T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
@@ -1545,6 +1546,11 @@
}
}
}
+ } else {
+ android_errorWriteLog(0x534e4554, "120502559");
+ GKI_freebuf(p_msg_rsp);
+ nfc_status = NFC_STATUS_FAILED;
+ LOG(ERROR) << StringPrintf("Underflow in p_msg_rsp->len!");
}
/* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if