Merge branch 'security-aosp-pi-release' into int/p/fp2

* security-aosp-pi-release:
  Type confusion due to race condition on tag type change

Change-Id: Ib5ab58df7a50ee111106f30554cba19ed4ce642a
diff --git a/src/nfa/rw/nfa_rw_main.cc b/src/nfa/rw/nfa_rw_main.cc
index a8f83b5..9023f4a 100644
--- a/src/nfa/rw/nfa_rw_main.cc
+++ b/src/nfa/rw/nfa_rw_main.cc
@@ -29,6 +29,7 @@
 #include "nfa_dm_int.h"
 #include "nfa_rw_api.h"
 #include "nfa_rw_int.h"
+#include "rw_int.h"
 
 using android::base::StringPrintf;
 
@@ -87,6 +88,54 @@
 **
 *******************************************************************************/
 void nfa_rw_sys_disable(void) {
+  tRW_T1T_CB* p_t1t;
+  tRW_T2T_CB* p_t2t;
+  tRW_T3T_CB* p_t3t;
+  tRW_T4T_CB* p_t4t;
+  tRW_I93_CB* p_i93;
+
+  DLOG_IF(INFO, nfc_debug_enabled) << __func__;
+
+  switch (rw_cb.tcb_type) {
+    case RW_CB_TYPE_T1T:
+      p_t1t = &rw_cb.tcb.t1t;
+      if (p_t1t->p_cur_cmd_buf != NULL) {
+        GKI_freebuf(p_t1t->p_cur_cmd_buf);
+        p_t1t->p_cur_cmd_buf = NULL;
+      }
+      break;
+    case RW_CB_TYPE_T2T:
+      p_t2t = &rw_cb.tcb.t2t;
+      if (p_t2t->p_cur_cmd_buf != NULL) {
+        GKI_freebuf(p_t2t->p_cur_cmd_buf);
+        p_t2t->p_cur_cmd_buf = NULL;
+      }
+      if (p_t2t->p_sec_cmd_buf != NULL) {
+        GKI_freebuf(p_t2t->p_sec_cmd_buf);
+        p_t2t->p_sec_cmd_buf = NULL;
+      }
+      break;
+    case RW_CB_TYPE_T3T:
+      p_t3t = &rw_cb.tcb.t3t;
+      if (p_t3t->p_cur_cmd_buf != NULL) {
+        GKI_freebuf(p_t3t->p_cur_cmd_buf);
+        p_t3t->p_cur_cmd_buf = NULL;
+      }
+      break;
+    case RW_CB_TYPE_T4T: /* do nothing */
+      p_t4t = &rw_cb.tcb.t4t;
+      break;
+    case RW_CB_TYPE_T5T:
+      p_i93 = &rw_cb.tcb.i93;
+      if (p_i93->p_retry_cmd != NULL) {
+        GKI_freebuf(p_i93->p_retry_cmd);
+        p_i93->p_retry_cmd = NULL;
+      }
+      break;
+    default: /* do nothing */
+      break;
+  }
+
   /* Return to idle */
   NFC_SetStaticRfCback(NULL);
 
diff --git a/src/nfc/include/rw_int.h b/src/nfc/include/rw_int.h
index cf6440b..72d24ab 100644
--- a/src/nfc/include/rw_int.h
+++ b/src/nfc/include/rw_int.h
@@ -698,8 +698,18 @@
   tRW_I93_CB i93;
 } tRW_TCB;
 
+/* RW callback type */
+#define RW_CB_TYPE_UNKNOWN 0
+#define RW_CB_TYPE_T1T 1
+#define RW_CB_TYPE_T2T 2
+#define RW_CB_TYPE_T3T 3
+#define RW_CB_TYPE_T4T 4
+#define RW_CB_TYPE_T5T 5
+typedef uint8_t tRW_CB_TYPE;
+
 /* RW control blocks */
 typedef struct {
+  tRW_CB_TYPE tcb_type;
   tRW_TCB tcb;
   tRW_CBACK* p_cback;
   uint32_t cur_retry; /* Retry count for the current operation */
diff --git a/src/nfc/tags/rw_main.cc b/src/nfc/tags/rw_main.cc
index 34dadae..3c2c076 100644
--- a/src/nfc/tags/rw_main.cc
+++ b/src/nfc/tags/rw_main.cc
@@ -33,6 +33,7 @@
 #include "bt_types.h"
 #include "nci_hmsgs.h"
 #include "nfc_api.h"
+#include "nfc_int.h"
 #include "rw_api.h"
 #include "rw_int.h"
 
@@ -214,6 +215,33 @@
     return (NFC_STATUS_FAILED);
   }
 
+  switch (rw_cb.tcb_type) {
+    case RW_CB_TYPE_T1T: {
+      nfc_stop_quick_timer(&rw_cb.tcb.t1t.timer);
+      break;
+    }
+    case RW_CB_TYPE_T2T: {
+      nfc_stop_quick_timer(&rw_cb.tcb.t2t.t2_timer);
+      break;
+    }
+    case RW_CB_TYPE_T3T: {
+      nfc_stop_quick_timer(&rw_cb.tcb.t3t.timer);
+      nfc_stop_quick_timer(&rw_cb.tcb.t3t.poll_timer);
+      break;
+    }
+    case RW_CB_TYPE_T4T: {
+      nfc_stop_quick_timer(&rw_cb.tcb.t4t.timer);
+      break;
+    }
+    case RW_CB_TYPE_T5T: {
+      nfc_stop_quick_timer(&rw_cb.tcb.i93.timer);
+      break;
+    }
+    case RW_CB_TYPE_UNKNOWN: {
+      break;
+    }
+  }
+
   /* Reset tag-specific area of control block */
   memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));
 
@@ -227,12 +255,14 @@
   if (NFC_PROTOCOL_T1T == p_activate_params->protocol) {
     /* Type1Tag    - NFC-A */
     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
+      rw_cb.tcb_type = RW_CB_TYPE_T1T;
       status = rw_t1t_select(p_activate_params->rf_tech_param.param.pa.hr,
                              p_activate_params->rf_tech_param.param.pa.nfcid1);
     }
   } else if (NFC_PROTOCOL_T2T == p_activate_params->protocol) {
     /* Type2Tag    - NFC-A */
     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
+      rw_cb.tcb_type = RW_CB_TYPE_T2T;
       if (p_activate_params->rf_tech_param.param.pa.sel_rsp ==
           NFC_SEL_RES_NFC_FORUM_T2T)
         status = rw_t2t_select();
@@ -240,6 +270,7 @@
   } else if (NFC_PROTOCOL_T3T == p_activate_params->protocol) {
     /* Type3Tag    - NFC-F */
     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) {
+      rw_cb.tcb_type = RW_CB_TYPE_T3T;
       status =
           rw_t3t_select(p_activate_params->rf_tech_param.param.pf.nfcid2,
                         p_activate_params->rf_tech_param.param.pf.mrti_check,
@@ -249,16 +280,19 @@
     /* ISODEP/4A,4B- NFC-A or NFC-B */
     if ((p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
         (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)) {
+      rw_cb.tcb_type = RW_CB_TYPE_T4T;
       status = rw_t4t_select();
     }
   } else if (NFC_PROTOCOL_T5T == p_activate_params->protocol) {
     /* T5T */
     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_V) {
+      rw_cb.tcb_type = RW_CB_TYPE_T5T;
       status = rw_i93_select(p_activate_params->rf_tech_param.param.pi93.uid);
     }
   }
   /* TODO set up callback for proprietary protocol */
   else {
+    rw_cb.tcb_type = RW_CB_TYPE_UNKNOWN;
     LOG(ERROR) << StringPrintf("RW_SetActivatedTagType Invalid protocol");
   }