Merge tag 'android-security-13.0.0_r8' into int/13/fp3

Android Security 13.0.0 Release 8 (10286630)

* tag 'android-security-13.0.0_r8':
  OOBW in rw_i93_send_to_upper()
  OOBW in nci_snd_set_routing_cmd()

Change-Id: Ib0f5da44dcf643551ca65a9d59b247b714c83dc2
diff --git a/src/Android.bp b/src/Android.bp
index f71c2e1..b419ef9 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -39,6 +39,7 @@
     cflags: [
         "-DDYN_ALLOC=1",
         "-DBUILDCFG=1",
+        "-DGKI_PTHREAD_JOINABLE",
         "-Wall",
         "-Werror",
         "-Wimplicit-fallthrough",
diff --git a/src/gki/ulinux/gki_ulinux.cc b/src/gki/ulinux/gki_ulinux.cc
index d6d81ed..336af3a 100644
--- a/src/gki/ulinux/gki_ulinux.cc
+++ b/src/gki/ulinux/gki_ulinux.cc
@@ -303,11 +303,16 @@
       while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
         usleep(100 * 1000);
 #else
-      /* wait for proper Arnold Schwarzenegger task state */
-      result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
-      if (result < 0) {
-        DLOG_IF(INFO, nfc_debug_enabled)
-            << StringPrintf("FAILED: result: %d", result);
+      /* Skip BTU_TASK due to BTU_TASK is used for GKI_run() and it terminates
+       * after GKI_shutdown().
+       */
+      if ((task_id - 1) != BTU_TASK) {
+        /* wait for proper Arnold Schwarzenegger task state */
+        result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
+        if (result < 0) {
+          DLOG_IF(INFO, nfc_debug_enabled)
+              << StringPrintf("FAILED: result: %d", result);
+        }
       }
 #endif
       DLOG_IF(INFO, nfc_debug_enabled)
diff --git a/src/nfa/ee/nfa_ee_act.cc b/src/nfa/ee/nfa_ee_act.cc
index 73c224c..bb083d8 100644
--- a/src/nfa/ee/nfa_ee_act.cc
+++ b/src/nfa/ee/nfa_ee_act.cc
@@ -409,15 +409,48 @@
   *ps = num_tlv;
 }
 
+/*******************************************************************************
+**
+** Function         nfa_ee_add_aid_route_to_ecb
+**
+** Description      Adds AIDs corresponding to ecb into listen mode routing
+**                  table(LMRT) buffer. Empty AID needs to be pushed as last
+**                  entry in LMRT. If Empty AID is part of any of the ecb,
+**                  its index is stored in tNFA_EE_EMPTY_AID_ECB structure.
+**                  If addEmptyAidRoute is set to true, only empty AID will
+**                  be added into LMRT buffer
+**
+** Returns          void
+**
+*******************************************************************************/
 static void nfa_ee_add_aid_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
                                         uint8_t* p, uint8_t* ps,
-                                        int* p_cur_offset, int* p_max_len) {
+                                        int* p_cur_offset, int* p_max_len,
+                                        tNFA_EE_EMPTY_AID_ECB& empty_aid_ecb) {
   uint8_t num_tlv = *ps;
 
   /* add the AID routing */
   if (p_cb->aid_entries) {
     int start_offset = 0;
-    for (int xx = 0; xx < p_cb->aid_entries; xx++) {
+    int xx = 0;
+    if (empty_aid_ecb.addEmptyAidRoute && empty_aid_ecb.index != -1) {
+      xx = empty_aid_ecb.index;
+      start_offset = empty_aid_ecb.offset;
+    }
+    for (; xx < p_cb->aid_entries; xx++) {
+      /*
+       * If addEmptyAidRoute is false and aid is empty AID don't add to the
+       * LMRT buffer. Instead update the empty aid ecb and index, which will
+       * be used later to add empty add at the end of the routing table
+       */
+      if (p_cb->aid_len[xx] == NFA_EMPTY_AID_TLV_LEN &&
+          !empty_aid_ecb.addEmptyAidRoute) {
+        empty_aid_ecb.p_cb = p_cb;
+        empty_aid_ecb.index = xx;
+        empty_aid_ecb.offset = start_offset;
+        start_offset += p_cb->aid_len[xx];
+        continue;
+      }
       /* remember the beginning of this AID routing entry, just in case we
        * need to put it in next command */
       uint8_t route_qual = 0;
@@ -464,6 +497,11 @@
         *ps = num_tlv;
         *p_cur_offset += new_size;
       }
+
+      if (empty_aid_ecb.addEmptyAidRoute) {
+        // Break the loop after adding Empty AID
+        break;
+      }
     }
   } else {
     DLOG_IF(INFO, nfc_debug_enabled)
@@ -645,8 +683,8 @@
                                     int* p_offset, int* p_entry) {
   int xx, yy, aid_len_offset, offset;
   tNFA_EE_ECB *p_ret = nullptr, *p_ecb;
-  /* NFA_EE_CB_4_DH + Empty aid ECB */
-  p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH + 1];
+
+  p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
   aid_len_offset = 1; /* skip the tag */
   for (yy = 0; yy <= nfa_ee_cb.cur_ee; yy++) {
     if (p_ecb->aid_entries) {
@@ -2592,9 +2630,9 @@
 ** Returns          NFA_STATUS_OK, if ok to continue
 **
 *******************************************************************************/
-void nfa_ee_route_add_one_ecb_by_route_order(tNFA_EE_ECB* p_cb, int rout_type,
-                                             int* p_max_len, bool more,
-                                             uint8_t* ps, int* p_cur_offset) {
+void nfa_ee_route_add_one_ecb_by_route_order(
+    tNFA_EE_ECB* p_cb, int rout_type, int* p_max_len, bool more, uint8_t* ps,
+    int* p_cur_offset, tNFA_EE_EMPTY_AID_ECB& empty_aid_ecb) {
   /* use the first byte of the buffer (ps) to keep the num_tlv */
   uint8_t num_tlv = *ps;
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
@@ -2621,7 +2659,8 @@
       nfa_ee_add_proto_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
     } break;
     case NCI_ROUTE_ORDER_AID: {
-      nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len);
+      nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len,
+                                  empty_aid_ecb);
     } break;
     case NCI_ROUTE_ORDER_SYS_CODE: {
       nfa_ee_add_sys_code_route_to_ecb(p_cb, pp, p, ps, p_cur_offset,
@@ -2834,6 +2873,10 @@
   cur_offset = 0;
   /* use the first byte of the buffer (p) to keep the num_tlv */
   *p = 0;
+  tNFA_EE_EMPTY_AID_ECB empty_aid_ecb;
+  memset(&empty_aid_ecb, 0x00, sizeof(tNFA_EE_EMPTY_AID_ECB));
+  empty_aid_ecb.index = -1;
+
   for (int rt = NCI_ROUTE_ORDER_AID; rt <= NCI_ROUTE_ORDER_TECHNOLOGY; rt++) {
     /* add the routing entries for NFCEEs */
     p_cb = &nfa_ee_cb.ecb[0];
@@ -2843,7 +2886,7 @@
         DLOG_IF(INFO, nfc_debug_enabled)
             << StringPrintf("%s --add the routing for NFCEEs!!", __func__);
         nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
-                                                &cur_offset);
+                                                &cur_offset, empty_aid_ecb);
       }
     }
     if (rt == NCI_ROUTE_ORDER_TECHNOLOGY) more = false;
@@ -2851,15 +2894,17 @@
     DLOG_IF(INFO, nfc_debug_enabled)
         << StringPrintf("%s --add the routing for DH!!", __func__);
     nfa_ee_route_add_one_ecb_by_route_order(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], rt,
-                                            &max_len, more, p, &cur_offset);
+                                            &max_len, more, p, &cur_offset,
+                                            empty_aid_ecb);
 
     if (rt == NCI_ROUTE_ORDER_AID) {
-      p_cb = &nfa_ee_cb.ecb[NFA_EE_EMPTY_AID_ECB];
-      if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+      if (empty_aid_ecb.p_cb) {
         DLOG_IF(INFO, nfc_debug_enabled)
-            << StringPrintf("%s --add the routing for Empty Aid!!", __func__);
-        nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
-                                                &cur_offset);
+            << StringPrintf("%s --add Empty AID routing", __func__);
+        empty_aid_ecb.addEmptyAidRoute = true;
+        nfa_ee_route_add_one_ecb_by_route_order(empty_aid_ecb.p_cb, rt,
+                                                &max_len, more, p, &cur_offset,
+                                                empty_aid_ecb);
       }
     }
   }
diff --git a/src/nfa/ee/nfa_ee_api.cc b/src/nfa/ee/nfa_ee_api.cc
index 428ac21..4206863 100644
--- a/src/nfa/ee/nfa_ee_api.cc
+++ b/src/nfa/ee/nfa_ee_api.cc
@@ -561,11 +561,7 @@
   tNFA_EE_ECB* p_cb;
 
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:<0x%x>", ee_handle);
-  if (aid_len == 0) {
-    p_cb = &nfa_ee_cb.ecb[NFA_EE_EMPTY_AID_ECB];
-  } else {
-    p_cb = nfa_ee_find_ecb(nfcee_id);
-  }
+  p_cb = nfa_ee_find_ecb(nfcee_id);
 
   /* validate parameters - make sure the AID is in valid length range */
   if ((p_cb == nullptr) ||
@@ -577,7 +573,6 @@
     LOG(ERROR) << StringPrintf("Bad ee_handle or AID (len=%d)", aid_len);
     status = NFA_STATUS_INVALID_PARAM;
   } else {
-    p_cb->nfcee_id = nfcee_id;
     p_msg = (tNFA_EE_API_ADD_AID*)GKI_getbuf(size);
     if (p_msg != nullptr) {
       if (p_aid != nullptr)
diff --git a/src/nfa/hci/nfa_hci_act.cc b/src/nfa/hci/nfa_hci_act.cc
index ae9c3b1..859c857 100644
--- a/src/nfa/hci/nfa_hci_act.cc
+++ b/src/nfa/hci/nfa_hci_act.cc
@@ -21,11 +21,10 @@
  *  This file contains the action functions for the NFA HCI.
  *
  ******************************************************************************/
-#include <string.h>
-
 #include <android-base/stringprintf.h>
 #include <base/logging.h>
 #include <log/log.h>
+#include <string.h>
 
 #include "nfa_dm_int.h"
 #include "nfa_hci_api.h"
@@ -1095,7 +1094,7 @@
 ** Returns          none
 **
 *******************************************************************************/
-void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) {
+void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data, uint16_t data_len) {
   uint8_t index;
   uint8_t data[2];
   uint8_t rsp_len = 0;
@@ -1110,15 +1109,23 @@
 
   switch (nfa_hci_cb.inst) {
     case NFA_HCI_ANY_SET_PARAMETER:
+      if (data_len < 1) {
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+      }
       STREAM_TO_UINT8(index, p_data);
 
-      if (index == 1) {
+      if (index == 1 && data_len > 2) {
         STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
       } else
         response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
       break;
 
     case NFA_HCI_ANY_GET_PARAMETER:
+      if (data_len < 1) {
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+      }
       STREAM_TO_UINT8(index, p_data);
       if (index == 1) {
         data[0] =
@@ -1189,7 +1196,7 @@
 ** Returns          none
 **
 *******************************************************************************/
-void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) {
+void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data, uint16_t data_len) {
   uint8_t source_host, source_gate, dest_host, dest_gate, pipe;
   uint8_t data = 0;
   uint8_t rsp_len = 0;
@@ -1215,6 +1222,10 @@
       break;
 
     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+      if (data_len < 5) {
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+      }
       STREAM_TO_UINT8(source_host, p_data);
       STREAM_TO_UINT8(source_gate, p_data);
       STREAM_TO_UINT8(dest_host, p_data);
@@ -1262,11 +1273,19 @@
       break;
 
     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
+      if (data_len < 1) {
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+      }
       STREAM_TO_UINT8(pipe, p_data);
       response = nfa_hciu_release_pipe(pipe);
       break;
 
     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+      if (data_len < 1) {
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+      }
       STREAM_TO_UINT8(source_host, p_data);
 
       nfa_hciu_remove_all_pipes_from_host(source_host);
diff --git a/src/nfa/hci/nfa_hci_main.cc b/src/nfa/hci/nfa_hci_main.cc
index 2ee1e03..b51c366 100644
--- a/src/nfa/hci/nfa_hci_main.cc
+++ b/src/nfa/hci/nfa_hci_main.cc
@@ -829,7 +829,7 @@
     case NFA_HCI_ADMIN_PIPE:
       /* Check if data packet is a command, response or event */
       if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
-        nfa_hci_handle_admin_gate_cmd(p);
+        nfa_hci_handle_admin_gate_cmd(p, pkt_len);
       } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
         nfa_hci_handle_admin_gate_rsp(p, (uint8_t)pkt_len);
       } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
@@ -840,7 +840,7 @@
     case NFA_HCI_LINK_MANAGEMENT_PIPE:
       /* We don't send Link Management commands, we only get them */
       if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
-        nfa_hci_handle_link_mgm_gate_cmd(p);
+        nfa_hci_handle_link_mgm_gate_cmd(p, pkt_len);
       break;
 
     default:
diff --git a/src/nfa/include/nfa_ee_int.h b/src/nfa/include/nfa_ee_int.h
index b280562..5cf6fe5 100644
--- a/src/nfa/include/nfa_ee_int.h
+++ b/src/nfa/include/nfa_ee_int.h
@@ -30,12 +30,10 @@
 /*****************************************************************************
 **  Constants and data types
 *****************************************************************************/
-/* the number of tNFA_EE_ECBs (for NFCEEs and DH) + Empty aid ECB */
-#define NFA_EE_NUM_ECBS (NFA_EE_MAX_EE_SUPPORTED + 2)
+/* the number of tNFA_EE_ECBs (for NFCEEs and DH) */
+#define NFA_EE_NUM_ECBS (NFA_EE_MAX_EE_SUPPORTED + 1)
 /* The index for DH in nfa_ee_cb.ee_cb[] */
 #define NFA_EE_CB_4_DH NFA_EE_MAX_EE_SUPPORTED
-/* The index for Empty aid in nfa_ee_cb.ee_cb[] */
-#define NFA_EE_EMPTY_AID_ECB (NFA_EE_CB_4_DH + 1)
 #define NFA_EE_INVALID 0xFF
 /* only A, B, F, Bprime are supported by UICC now */
 #define NFA_EE_MAX_TECH_ROUTE 4
@@ -151,6 +149,8 @@
 /* this bit is in ee_status for internal use only */
 #define NFA_EE_STATUS_INT_MASK 0x20
 
+#define NFA_EMPTY_AID_TLV_LEN 0x02
+
 /* NFA-EE information for a particular NFCEE Entity (including DH) */
 typedef struct {
   tNFA_TECHNOLOGY_MASK
@@ -225,6 +225,14 @@
   uint16_t size_sys_code; /* The size for system code routing */
 } tNFA_EE_ECB;
 
+/* data type for Empty AID Index and ECB */
+typedef struct {
+  tNFA_EE_ECB* p_cb;
+  uint16_t index;
+  bool addEmptyAidRoute;
+  int offset;
+} tNFA_EE_EMPTY_AID_ECB;
+
 /* data type for NFA_EE_API_DISCOVER_EVT */
 typedef struct {
   NFC_HDR hdr;
diff --git a/src/nfa/include/nfa_hci_int.h b/src/nfa/include/nfa_hci_int.h
index c9c9550..e91def3 100644
--- a/src/nfa/include/nfa_hci_int.h
+++ b/src/nfa/include/nfa_hci_int.h
@@ -24,7 +24,9 @@
 #ifndef NFA_HCI_INT_H
 #define NFA_HCI_INT_H
 
+#include <cstdint>
 #include <string>
+
 #include "nfa_ee_api.h"
 #include "nfa_hci_api.h"
 #include "nfa_sys.h"
@@ -449,10 +451,11 @@
 */
 extern void nfa_hci_check_pending_api_requests(void);
 extern void nfa_hci_check_api_requests(void);
-extern void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data);
+extern void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data, uint16_t data_len);
 extern void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len);
 extern void nfa_hci_handle_admin_gate_evt();
-extern void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data);
+extern void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data,
+                                             uint16_t data_len);
 extern void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe, uint8_t* p_data,
                                         uint16_t data_len);
 extern void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe);
diff --git a/src/nfc/nfc/nfc_ncif.cc b/src/nfc/nfc/nfc_ncif.cc
index 47d00de..3085f26 100644
--- a/src/nfc/nfc/nfc_ncif.cc
+++ b/src/nfc/nfc/nfc_ncif.cc
@@ -1874,8 +1874,7 @@
             }
           }
         }
-        if ((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
-            (p_cb->act_protocol == NCI_PROTOCOL_T5T)) {
+        if (p_cb->act_protocol == NCI_PROTOCOL_T5T) {
           p_evt->len--;
           p = (uint8_t*)(p_evt + 1);
           data_cevt.status = *(p + p_evt->offset + p_evt->len);
diff --git a/src/nfc/nfc/nfc_task.cc b/src/nfc/nfc/nfc_task.cc
index 5fe07ab..023e56a 100644
--- a/src/nfc/nfc/nfc_task.cc
+++ b/src/nfc/nfc/nfc_task.cc
@@ -358,7 +358,7 @@
   /* main loop */
   while (true) {
     event = GKI_wait(0xFFFF, 0);
-    if (event == EVENT_MASK(GKI_SHUTDOWN_EVT)) {
+    if (event & EVENT_MASK(GKI_SHUTDOWN_EVT)) {
       break;
     }
     /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
diff --git a/src/nfc/tags/rw_t3t.cc b/src/nfc/tags/rw_t3t.cc
index 0e91498..9bd6541 100644
--- a/src/nfc/tags/rw_t3t.cc
+++ b/src/nfc/tags/rw_t3t.cc
@@ -1571,6 +1571,12 @@
        * bytes (do not include padding to 16-byte boundary) */
       if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
           (p_cb->ndef_attrib.ln & 0x000F)) {
+        if (rsp_num_bytes_rx < (16 - (p_cb->ndef_attrib.ln & 0x000F))) {
+          nfc_status = NFC_STATUS_FAILED;
+          GKI_freebuf(p_msg_rsp);
+          android_errorWriteLog(0x534e4554, "224002331");
+          return;
+        }
         rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
       }