Prevent OOB read in rw_i93_process_sys_info()
Test: Nfc Enable/Disable
Bug: 121259048
Change-Id: Iad8809e5d270f1049b3738891ef4b44346084047
(cherry picked from commit c1da325665ece30e0d1a0e9ab0c9113909739bcf)
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index 42a9c1c..b4d73e2 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -263,38 +263,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 */
@@ -495,7 +522,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;
@@ -1647,7 +1674,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;
}
@@ -2373,7 +2400,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;
}