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