Prevent OOB in nfc_ncif_proc_get_routing

Bug: 122358602
Bug: 155284475
Test: manual
Change-Id: I0a39e17c69b52bf13b22d7722c4ef18e65177068
diff --git a/src/nfc/include/nfc_api.h b/src/nfc/include/nfc_api.h
index 84a1426..5e4d6ca 100644
--- a/src/nfc/include/nfc_api.h
+++ b/src/nfc/include/nfc_api.h
@@ -313,6 +313,7 @@
   uint8_t nfcee_id;   /* NFCEE ID                         */
   uint8_t num_tlvs;   /* number of TLVs                   */
   uint8_t tlv_size;   /* the total len of all TLVs        */
+  uint8_t qualifier_type;                  /* qualifier type */
   uint8_t param_tlvs[NFC_MAX_EE_TLV_SIZE]; /* the TLVs         */
 } tNFC_GET_ROUTING_REVT;
 
diff --git a/src/nfc/nfc/nfc_ncif.cc b/src/nfc/nfc/nfc_ncif.cc
index 489b84f..c319784 100644
--- a/src/nfc/nfc/nfc_ncif.cc
+++ b/src/nfc/nfc/nfc_ncif.cc
@@ -1546,34 +1546,42 @@
 ** Returns          void
 **
 *******************************************************************************/
-void nfc_ncif_proc_get_routing(uint8_t* p,
-                               __attribute__((unused)) uint8_t len) {
+void nfc_ncif_proc_get_routing(uint8_t* p, uint8_t len) {
   tNFC_GET_ROUTING_REVT evt_data;
-  uint8_t more, num_entries, xx, yy, *pn, tl;
+  uint8_t more, num_entries, xx, *pn;
   tNFC_STATUS status = NFC_STATUS_CONTINUE;
 
-  if (nfc_cb.p_resp_cback) {
+  if (len >= 2 && nfc_cb.p_resp_cback) {
     more = *p++;
     num_entries = *p++;
+    if (num_entries == 0) return;
+    len -= 2;
+    if (len < 2) {
+      LOG(ERROR) << StringPrintf("Invalid len=%d", len);
+      return;
+    }
     for (xx = 0; xx < num_entries; xx++) {
       if ((more == false) && (xx == (num_entries - 1))) status = NFC_STATUS_OK;
       evt_data.status = (tNFC_STATUS)status;
-      evt_data.nfcee_id = *p++;
-      evt_data.num_tlvs = *p++;
-      evt_data.tlv_size = 0;
-      pn = evt_data.param_tlvs;
-      for (yy = 0; yy < evt_data.num_tlvs; yy++) {
-        tl = *(p + 1);
-        tl += NFC_TL_SIZE;
-        evt_data.tlv_size += tl;
-        if (evt_data.tlv_size > NFC_MAX_EE_TLV_SIZE) {
-          android_errorWriteLog(0x534e4554, "117554809");
-          LOG(ERROR) << __func__ << "Invalid data format";
-          return;
-        }
-        STREAM_TO_ARRAY(pn, p, tl);
-        pn += tl;
+      if (len >= 2)
+        len -= 2;
+      else
+        return;
+      evt_data.qualifier_type = *p++;
+      evt_data.num_tlvs = 1;
+      evt_data.tlv_size = *p++;
+      if (evt_data.tlv_size > NFC_MAX_EE_TLV_SIZE) {
+        android_errorWriteLog(0x534e4554, "117554809");
+        LOG(ERROR) << __func__ << "Invalid data format";
+        return;
       }
+      if (evt_data.tlv_size > len) {
+        LOG(ERROR) << StringPrintf("Invalid evt_data.tlv_size");
+        return;
+      } else
+        len -= evt_data.tlv_size;
+      pn = evt_data.param_tlvs;
+      STREAM_TO_ARRAY(pn, p, evt_data.tlv_size);
       tNFC_RESPONSE nfc_response;
       nfc_response.get_routing = evt_data;
       (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, &nfc_response);