Merge "Prevent OOB read in rw_i93_process_sys_info()" into oc-dev am: 2c605825f8 am: 6430e95d82
am: 404c66d3f1
Change-Id: I23a0c2be3563c3dae9b2835e2605b82fd946d064
(cherry picked from commit 34eb9823a391c1a47e2addfba094ea56106f8112)
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index 48edb76..5d75605 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -264,38 +264,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 */
@@ -496,7 +523,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;
@@ -1658,7 +1685,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;
}
@@ -2413,7 +2440,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;
}