Merge the android-9.0.0_r55 release tag
Android 9.0.0 Release 55 (6197209)

* tag 'android-9.0.0_r55':
  OOB write in rw_t2t_ndef.cc
  OOB write in rw_t2t_handle_tlv_detect_rsp
  Prevent information disclosure in rw_i93.cc
  Prevent uncleared memory leaking in rw_i93.cc
  Add boundary check in nfa_hci_handle_admin_gate_rsp
  Prevent OOB in rw_i93.cc

Change-Id: I3382e95efb919d49fa59a67a355602d8e04632c2
diff --git a/src/nfa/hci/nfa_hci_act.cc b/src/nfa/hci/nfa_hci_act.cc
index 1e50670..c75c1c6 100644
--- a/src/nfa/hci/nfa_hci_act.cc
+++ b/src/nfa/hci/nfa_hci_act.cc
@@ -25,6 +25,7 @@
 
 #include <android-base/stringprintf.h>
 #include <base/logging.h>
+#include <log/log.h>
 
 #include "nfa_dm_int.h"
 #include "nfa_hci_api.h"
@@ -1389,7 +1390,8 @@
         } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
           /* The only parameter we get when initializing is the session ID.
            * Check for match. */
-          if (!memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
+          if (data_len >= NFA_HCI_SESSION_ID_LEN &&
+              !memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
                       NFA_HCI_SESSION_ID_LEN)) {
             /* Session has not changed, Set WHITELIST */
             nfa_hciu_send_set_param_cmd(
@@ -1400,6 +1402,9 @@
              * default session id */
             nfa_hciu_send_clear_all_pipe_cmd();
             nfa_hci_cb.b_hci_netwk_reset = true;
+            if (data_len < NFA_HCI_SESSION_ID_LEN) {
+              android_errorWriteLog(0x534e4554, "124524315");
+            }
           }
         }
         break;
@@ -1452,7 +1457,8 @@
 
       case NFA_HCI_ANY_GET_PARAMETER:
         if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
-          if (!memcmp((uint8_t*)default_session, p_data,
+          if (data_len >= NFA_HCI_SESSION_ID_LEN &&
+              !memcmp((uint8_t*)default_session, p_data,
                       NFA_HCI_SESSION_ID_LEN)) {
             memcpy(&nfa_hci_cb.cfg.admin_gate
                         .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
@@ -1467,6 +1473,9 @@
                 NFA_HCI_SESSION_ID_LEN,
                 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
           } else {
+            if (data_len < NFA_HCI_SESSION_ID_LEN) {
+              android_errorWriteLog(0x534e4554, "124524315");
+            }
             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
               nfa_hci_api_deregister(NULL);
             else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
@@ -1474,6 +1483,10 @@
           }
         } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
           evt_data.hosts.status = status;
+          if (data_len > NFA_HCI_MAX_HOST_IN_NETWORK) {
+            data_len = NFA_HCI_MAX_HOST_IN_NETWORK;
+            android_errorWriteLog(0x534e4554, "124524315");
+          }
           evt_data.hosts.num_hosts = data_len;
           memcpy(evt_data.hosts.host, p_data, data_len);
 
@@ -1505,7 +1518,8 @@
         break;
 
       case NFA_HCI_ADM_CREATE_PIPE:
-        if (status == NFA_STATUS_OK) {
+        // p_data should have at least 5 bytes length for pipe info
+        if (data_len >= 5 && status == NFA_STATUS_OK) {
           STREAM_TO_UINT8(source_host, p_data);
           STREAM_TO_UINT8(source_gate, p_data);
           STREAM_TO_UINT8(dest_host, p_data);
@@ -1522,6 +1536,9 @@
           }
 
           nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
+        } else if (data_len < 5 && status == NFA_STATUS_OK) {
+          android_errorWriteLog(0x534e4554, "124524315");
+          status = NFA_STATUS_FAILED;
         }
 
         /* Tell the application his pipe was created or not */
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index a8e095c..983eafa 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -51,6 +51,8 @@
 #define RW_I93_FORMAT_DATA_LEN 8
 /* max getting lock status if get multi block sec is supported */
 #define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
+/*Capability Container CC Size */
+#define RW_I93_CC_SIZE 4
 
 /* main state */
 enum {
@@ -1734,8 +1736,14 @@
 
     case RW_I93_SUBSTATE_WAIT_CC:
 
-      /* assume block size is more than 4 */
-      STREAM_TO_ARRAY(cc, p, 4);
+      if (length < RW_I93_CC_SIZE) {
+        android_errorWriteLog(0x534e4554, "139188579");
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+        return;
+      }
+
+      /* assume block size is more than RW_I93_CC_SIZE 4 */
+      STREAM_TO_ARRAY(cc, p, RW_I93_CC_SIZE);
 
       status = NFC_STATUS_FAILED;
 
@@ -2215,8 +2223,11 @@
 
       block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
 
-      if (rw_i93_send_cmd_write_single_block(block_number, p) ==
-          NFC_STATUS_OK) {
+      if (length < p_i93->block_size) {
+        android_errorWriteLog(0x534e4554, "143109193");
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
+                 NFC_STATUS_OK) {
         /* update next writing offset */
         p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
         p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
@@ -2370,8 +2381,11 @@
 
           block_number = (p_i93->rw_offset / p_i93->block_size);
 
-          if (rw_i93_send_cmd_write_single_block(block_number, p) ==
-              NFC_STATUS_OK) {
+          if (length < p_i93->block_size) {
+            android_errorWriteLog(0x534e4554, "143155861");
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
+                     NFC_STATUS_OK) {
             /* set offset to the beginning of next block */
             p_i93->rw_offset +=
                 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
@@ -2631,12 +2645,20 @@
       }
 
       /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
-      p_i93->p_update_data = (uint8_t*)GKI_getbuf(RW_I93_FORMAT_DATA_LEN);
+      /* Block size could be either 4 or 8 or 16 or 32 bytes */
+      /* Get buffer for the largest block size I93_MAX_BLOCK_LENGH */
+      p_i93->p_update_data = (uint8_t*)GKI_getbuf(I93_MAX_BLOCK_LENGH);
 
       if (!p_i93->p_update_data) {
         LOG(ERROR) << StringPrintf("Cannot allocate buffer");
         rw_i93_handle_error(NFC_STATUS_FAILED);
         break;
+      } else if (p_i93->block_size > RW_I93_FORMAT_DATA_LEN) {
+        /* Possible leaking information from previous NFC transactions */
+        /* Clear previous values */
+        memset(p_i93->p_update_data, I93_ICODE_TLV_TYPE_NULL,
+               I93_MAX_BLOCK_LENGH);
+        android_errorWriteLog(0x534e4554, "139738828");
       }
 
       p = p_i93->p_update_data;
@@ -2775,10 +2797,19 @@
   switch (p_i93->sub_state) {
     case RW_I93_SUBSTATE_WAIT_CC:
 
+      if (length < RW_I93_CC_SIZE) {
+        android_errorWriteLog(0x534e4554, "139188579");
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+        return;
+      }
+
       /* mark CC as read-only */
       *(p + 1) |= I93_ICODE_CC_READ_ONLY;
 
-      if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
+      if (length < p_i93->block_size) {
+        android_errorWriteLog(0x534e4554, "143106535");
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      } else if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
         p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
       } else {
         rw_i93_handle_error(NFC_STATUS_FAILED);
diff --git a/src/nfc/tags/rw_t2t_ndef.cc b/src/nfc/tags/rw_t2t_ndef.cc
index c18c685..36c7fec 100644
--- a/src/nfc/tags/rw_t2t_ndef.cc
+++ b/src/nfc/tags/rw_t2t_ndef.cc
@@ -601,6 +601,12 @@
               android_errorWriteLog(0x534e4554, "120506143");
             }
             if ((tlvtype == TAG_LOCK_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
+              if (p_t2t->num_lockbytes > 0) {
+                LOG(ERROR) << StringPrintf("Malformed tag!");
+                android_errorWriteLog(0x534e4554, "147309942");
+                failed = true;
+                break;
+              }
               /* Collect Lock TLV */
               p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
               if (p_t2t->bytes_count == 0) {
@@ -614,10 +620,19 @@
                     p_t2t->tlv_value[0] & 0x0F;
                 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
                     (uint8_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
-                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits =
-                    p_t2t->tlv_value[1];
-                count = p_t2t->tlv_value[1] / 8 +
-                        ((p_t2t->tlv_value[1] % 8 != 0) ? 1 : 0);
+                /* Note: 0 value in DLA_NbrLockBits means 256 */
+                count = p_t2t->tlv_value[1];
+                /* Set it to max value that can be stored in lockbytes */
+                if (count == 0) {
+#if RW_T2T_MAX_LOCK_BYTES > 0x1F
+                  count = UCHAR_MAX;
+#else
+                  count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
+#endif
+                }
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = count;
+                count = count / TAG_BITS_PER_BYTE +
+                        ((count % TAG_BITS_PER_BYTE != 0) ? 1 : 0);
 
                 /* Extract lockbytes info addressed by this Lock TLV */
                 xx = 0;
@@ -856,6 +871,14 @@
         bytes_locked_per_lock_bit;
     num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
     num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0 : 1;
+    if (num_dynamic_lock_bytes > RW_T2T_MAX_LOCK_BYTES) {
+      LOG(ERROR) << StringPrintf(
+          "rw_t2t_extract_default_locks_info - buffer size: %u less than "
+          "DynLock area sise: %u",
+          RW_T2T_MAX_LOCK_BYTES, num_dynamic_lock_bytes);
+      num_dynamic_lock_bytes = RW_T2T_MAX_LOCK_BYTES;
+      android_errorWriteLog(0x534e4554, "147310721");
+    }
 
     p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
         (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
@@ -2251,7 +2274,8 @@
           if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
               rw_t2t_mask_bits[xx]) {
             /* If the bit is set then it is locked */
-            p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
+            if (block_count < RW_T2T_SEGMENT_SIZE)
+              p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
           }
           bytes_covered++;
           bits_covered++;