Merge branch 'dev/11/fp3/security-aosp-rvc-release' into int/11/fp3
* dev/11/fp3/security-aosp-rvc-release:
OOBW in nci_snd_set_routing_cmd()
Change-Id: I600a91afb6b9d8f978e5026b1fb39ea8a1e38770
diff --git a/src/adaptation/NfcAdaptation.cc b/src/adaptation/NfcAdaptation.cc
index b0fc549..2af25cf 100644
--- a/src/adaptation/NfcAdaptation.cc
+++ b/src/adaptation/NfcAdaptation.cc
@@ -411,6 +411,9 @@
} else if (mHal_1_1 != nullptr) {
mHal_1_1->closeForPowerOffCase();
}
+ if (mHal) {
+ mHal->unlinkToDeath(mNfcHalDeathRecipient);
+ }
}
/*******************************************************************************
diff --git a/src/nfa/rw/nfa_rw_api.cc b/src/nfa/rw/nfa_rw_api.cc
index 9f176d2..1c130f7 100644
--- a/src/nfa/rw/nfa_rw_api.cc
+++ b/src/nfa/rw/nfa_rw_api.cc
@@ -25,6 +25,7 @@
#include <android-base/stringprintf.h>
#include <base/logging.h>
+#include <log/log.h>
#include "nfa_api.h"
#include "nfa_rw_int.h"
@@ -1097,7 +1098,7 @@
uint16_t number_blocks,
uint8_t* p_data) {
tNFA_RW_OPERATION* p_msg;
- uint16_t data_length;
+ uint32_t data_length;
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("%d, %d", first_block_number, number_blocks);
@@ -1113,6 +1114,11 @@
data_length = nfa_rw_cb.i93_block_size * number_blocks;
+ if (data_length + sizeof(tNFA_RW_OPERATION) > UINT16_MAX) {
+ android_errorWriteLog(0x534e4554, "157650338");
+ return (NFA_STATUS_FAILED);
+ }
+
p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
(uint16_t)(sizeof(tNFA_RW_OPERATION) + data_length));
if (p_msg != nullptr) {
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/nci/nci_hrcv.cc b/src/nfc/nci/nci_hrcv.cc
index 737bc9d..7dfa408 100644
--- a/src/nfc/nci/nci_hrcv.cc
+++ b/src/nfc/nci/nci_hrcv.cc
@@ -26,6 +26,7 @@
#include <android-base/stringprintf.h>
#include <base/logging.h>
+#include <log/log.h>
#include "nfc_target.h"
@@ -252,6 +253,11 @@
break;
case NCI_MSG_RF_DEACTIVATE:
+ if (p_msg->len < 5) {
+ /* NCI_HEADER(3) + Deactivation Type(1) + Deactivation Reason(1) */
+ android_errorWriteLog(0x534e4554, "164440989");
+ return;
+ }
if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
return;
}
@@ -408,58 +414,93 @@
<< StringPrintf("nci_proc_ee_management_ntf opcode:0x%x", op_code);
len = *pp++;
- if (op_code == NCI_MSG_NFCEE_DISCOVER) {
- nfc_response.nfcee_info.nfcee_id = *pp++;
+ switch (op_code) {
+ case NCI_MSG_NFCEE_DISCOVER:
+ if (len < 3) {
+ p_cback = nullptr;
+ break;
+ } else {
+ len -= 3;
+ }
+ nfc_response.nfcee_info.nfcee_id = *pp++;
- nfc_response.nfcee_info.ee_status = *pp++;
- yy = *pp;
- nfc_response.nfcee_info.num_interface = *pp++;
- p = pp;
-
- if (nfc_response.nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
- nfc_response.nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
-
- for (xx = 0; xx < nfc_response.nfcee_info.num_interface; xx++) {
- nfc_response.nfcee_info.ee_interface[xx] = *pp++;
- }
-
- pp = p + yy;
- nfc_response.nfcee_info.num_tlvs = *pp++;
- DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
- "nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
- nfc_response.nfcee_info.nfcee_id, nfc_response.nfcee_info.num_interface,
- yy, nfc_response.nfcee_info.num_tlvs);
-
- if (nfc_response.nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
- nfc_response.nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
-
- p_tlv = &nfc_response.nfcee_info.ee_tlv[0];
-
- for (xx = 0; xx < nfc_response.nfcee_info.num_tlvs; xx++, p_tlv++) {
- p_tlv->tag = *pp++;
- p_tlv->len = yy = *pp++;
- DLOG_IF(INFO, nfc_debug_enabled)
- << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
- if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
+ nfc_response.nfcee_info.ee_status = *pp++;
+ yy = *pp;
+ nfc_response.nfcee_info.num_interface = *pp++;
+ if (len < yy + 1) {
+ p_cback = nullptr;
+ break;
+ } else {
+ len -= yy + 1;
+ }
p = pp;
- STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
- pp = p += yy;
- }
- } else if (op_code == NCI_MSG_NFCEE_MODE_SET) {
- nfc_response.mode_set.status = *pp;
- nfc_response.mode_set.nfcee_id = *p_old++;
- nfc_response.mode_set.mode = *p_old++;
- event = NFC_NFCEE_MODE_SET_REVT;
- nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
- nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer);
- } else if (op_code == NCI_MSG_NFCEE_STATUS) {
- event = NFC_NFCEE_STATUS_REVT;
- nfc_response.nfcee_status.status = NCI_STATUS_OK;
- nfc_response.nfcee_status.nfcee_id = *pp++;
- nfc_response.nfcee_status.nfcee_status = *pp;
- } else {
- p_cback = nullptr;
- LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
+
+ if (nfc_response.nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
+ nfc_response.nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
+
+ for (xx = 0; xx < nfc_response.nfcee_info.num_interface; xx++) {
+ nfc_response.nfcee_info.ee_interface[xx] = *pp++;
+ }
+
+ pp = p + yy;
+ nfc_response.nfcee_info.num_tlvs = *pp++;
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+ "nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
+ nfc_response.nfcee_info.nfcee_id,
+ nfc_response.nfcee_info.num_interface, yy,
+ nfc_response.nfcee_info.num_tlvs);
+
+ if (nfc_response.nfcee_info.num_tlvs > 0 && len < 2) {
+ p_cback = nullptr;
+ break;
+ }
+ if (nfc_response.nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
+ nfc_response.nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
+
+ p_tlv = &nfc_response.nfcee_info.ee_tlv[0];
+
+ for (xx = 0; xx < nfc_response.nfcee_info.num_tlvs; xx++, p_tlv++) {
+ p_tlv->tag = *pp++;
+ p_tlv->len = yy = *pp++;
+ if (len < yy + 2) {
+ p_cback = nullptr;
+ break;
+ } else {
+ len -= yy + 2;
+ }
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
+ if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
+ p = pp;
+ STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
+ pp = p += yy;
+ }
+ break;
+ case NCI_MSG_NFCEE_MODE_SET:
+ if (len < 1) {
+ nfc_response.mode_set.status = NCI_STATUS_MESSAGE_CORRUPTED;
+ } else {
+ nfc_response.mode_set.status = *pp;
+ }
+ nfc_response.mode_set.nfcee_id = *p_old++;
+ nfc_response.mode_set.mode = *p_old++;
+ event = NFC_NFCEE_MODE_SET_REVT;
+ nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
+ nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer);
+ break;
+ case NCI_MSG_NFCEE_STATUS:
+ event = NFC_NFCEE_STATUS_REVT;
+ if (len < 2) {
+ nfc_response.nfcee_status.status = NCI_STATUS_MESSAGE_CORRUPTED;
+ break;
+ }
+ nfc_response.nfcee_status.status = NCI_STATUS_OK;
+ nfc_response.nfcee_status.nfcee_id = *pp++;
+ nfc_response.nfcee_status.nfcee_status = *pp;
+ break;
+ default:
+ p_cback = nullptr;
+ LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
}
if (p_cback) (*p_cback)(event, &nfc_response);
diff --git a/src/nfc/nfc/nfc_main.cc b/src/nfc/nfc/nfc_main.cc
index 991d320..a03fa7a 100644
--- a/src/nfc/nfc/nfc_main.cc
+++ b/src/nfc/nfc/nfc_main.cc
@@ -317,8 +317,9 @@
memcpy(evt_data.enable.vs_interface, nfc_cb.vs_interface,
NFC_NFCC_MAX_NUM_VS_INTERFACE);
} else {
- /* one byte is consumed in the top expression */
- lremain -= sizeof(uint16_t) + NFC_NFCC_INFO_LEN;
+ /* For VERSION_UNKNOWN one byte is consumed in the top expression */
+ lremain -= sizeof(uint16_t) + NFC_NFCC_INFO_LEN +
+ (nfc_cb.nci_version == NCI_VERSION_1_0 ? 1 : 0);
if (lremain < 0) {
nfc_status = NCI_STATUS_FAILED;
goto plen_err;
diff --git a/src/nfc/nfc/nfc_ncif.cc b/src/nfc/nfc/nfc_ncif.cc
index d741101..93a3509 100644
--- a/src/nfc/nfc/nfc_ncif.cc
+++ b/src/nfc/nfc/nfc_ncif.cc
@@ -1426,16 +1426,26 @@
void nfc_ncif_proc_ee_action(uint8_t* p, uint16_t plen) {
tNFC_EE_ACTION_REVT evt_data;
tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+ tNFC_RESPONSE nfc_response;
uint8_t data_len, ulen, tag, *p_data;
uint8_t max_len;
if (p_cback) {
memset(&evt_data.act_data, 0, sizeof(tNFC_ACTION_DATA));
+ if (plen > 3) {
+ plen -= 3;
+ } else {
+ evt_data.status = NFC_STATUS_FAILED;
+ evt_data.nfcee_id = 0;
+ nfc_response.ee_action = evt_data;
+ (*p_cback)(NFC_EE_ACTION_REVT, &nfc_response);
+ android_errorWriteLog(0x534e4554, "157649306");
+ return;
+ }
evt_data.status = NFC_STATUS_OK;
evt_data.nfcee_id = *p++;
evt_data.act_data.trigger = *p++;
data_len = *p++;
- if (plen >= 3) plen -= 3;
if (data_len > plen) data_len = (uint8_t)plen;
switch (evt_data.act_data.trigger) {
@@ -1478,7 +1488,6 @@
}
break;
}
- tNFC_RESPONSE nfc_response;
nfc_response.ee_action = evt_data;
(*p_cback)(NFC_EE_ACTION_REVT, &nfc_response);
}
@@ -1551,34 +1560,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);
@@ -1870,13 +1887,13 @@
data_cevt.p_data = p_evt;
/* adjust payload, if needed */
- if (p_cb->conn_id == NFC_RF_CONN_ID) {
+ if (p_cb->conn_id == NFC_RF_CONN_ID && p_evt->len) {
/* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status
* byte needs to be removed
*/
if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) &&
(p_cb->act_protocol <= NCI_PROTOCOL_T3T)) {
- if (p_evt->len) p_evt->len--;
+ p_evt->len--;
p = (uint8_t*)(p_evt + 1);
data_cevt.status = *(p + p_evt->offset + p_evt->len);
if ((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
@@ -1893,7 +1910,7 @@
}
if ((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
(p_cb->act_protocol == NCI_PROTOCOL_T5T)) {
- if (p_evt->len) p_evt->len--;
+ p_evt->len--;
p = (uint8_t*)(p_evt + 1);
data_cevt.status = *(p + p_evt->offset + p_evt->len);
}
diff --git a/src/nfc/tags/ce_main.cc b/src/nfc/tags/ce_main.cc
index 27c218c..1afc848 100644
--- a/src/nfc/tags/ce_main.cc
+++ b/src/nfc/tags/ce_main.cc
@@ -27,6 +27,7 @@
#include <android-base/stringprintf.h>
#include <base/logging.h>
+#include <log/log.h>
#include "nfc_target.h"
@@ -64,6 +65,12 @@
uint8_t* p;
if (ce_cb.p_cback) {
+ if (data_len > GKI_get_pool_bufsize(NFC_RW_POOL_ID) - NCI_MSG_OFFSET_SIZE -
+ NCI_DATA_HDR_SIZE - 1) {
+ android_errorWriteLog(0x534e4554, "157649398");
+ return NFC_STATUS_FAILED;
+ }
+
/* a valid opcode for RW */
p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
if (p_data) {
diff --git a/src/nfc/tags/ce_t4t.cc b/src/nfc/tags/ce_t4t.cc
index aa9bc39..a4196a2 100644
--- a/src/nfc/tags/ce_t4t.cc
+++ b/src/nfc/tags/ce_t4t.cc
@@ -732,7 +732,9 @@
BE_STREAM_TO_UINT8(length, p_cmd); /* Lc */
/* check if valid parameters */
- if ((uint32_t)length <= CE_T4T_MAX_LC) {
+ if ((uint32_t)length <= CE_T4T_MAX_LC &&
+ /* check if data fits into the apdu */
+ (uint16_t)length <= p_c_apdu->len - T4T_CMD_MAX_HDR_SIZE) {
if (length + offset > ce_cb.mem.t4t.max_file_size) {
LOG(ERROR) << StringPrintf(
"CET4T: length (%d) + offset (%d) must be less than "
@@ -744,6 +746,7 @@
LOG(ERROR) << StringPrintf(
"CET4T: length (%d) must be less than MLc (%zu)", length,
CE_T4T_MAX_LC);
+ android_errorWriteLog(0x534e4554, "157649298");
length = 0;
}
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index e06142b..1c64ea8 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -693,11 +693,17 @@
rw_cb.tcb.i93.p_retry_cmd = nullptr;
}
+ uint16_t msg_size = sizeof(NFC_HDR) + p_msg->offset + p_msg->len;
+
rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
- if (rw_cb.tcb.i93.p_retry_cmd) {
- memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
- sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
+ if (rw_cb.tcb.i93.p_retry_cmd &&
+ GKI_get_pool_bufsize(NFC_RW_POOL_ID) >= msg_size) {
+ memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg, msg_size);
+ } else {
+ LOG(ERROR) << StringPrintf("Memory allocation error");
+ android_errorWriteLog(0x534e4554, "157650357");
+ return false;
}
if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
@@ -1128,6 +1134,13 @@
DLOG_IF(INFO, nfc_debug_enabled) << __func__;
+ if (number_blocks * rw_cb.tcb.i93.block_size >
+ GKI_get_pool_bufsize(NFC_RW_POOL_ID) - NCI_MSG_OFFSET_SIZE -
+ NCI_DATA_HDR_SIZE - 1 -
+ (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS ? 2 : 0) - 12) {
+ android_errorWriteLog(0x534e4554, "157650365");
+ return NFC_STATUS_FAILED;
+ }
p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
if (!p_cmd) {
@@ -1163,9 +1176,6 @@
p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
}
- UINT8_TO_STREAM(
- p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
-
/* Data */
ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
@@ -4287,4 +4297,4 @@
default:
return "UNKNOWN";
}
-}
\ No newline at end of file
+}
diff --git a/src/nfc/tags/rw_main.cc b/src/nfc/tags/rw_main.cc
index 0c70638..abd8bbe 100644
--- a/src/nfc/tags/rw_main.cc
+++ b/src/nfc/tags/rw_main.cc
@@ -27,6 +27,7 @@
#include <android-base/stringprintf.h>
#include <base/logging.h>
+#include <log/log.h>
#include "nfc_target.h"
@@ -174,6 +175,11 @@
uint8_t* p;
if (rw_cb.p_cback) {
+ if (data_len > GKI_get_pool_bufsize(NFC_RW_POOL_ID) - NCI_MSG_OFFSET_SIZE -
+ NCI_DATA_HDR_SIZE - 1) {
+ android_errorWriteLog(0x534e4554, "157650117");
+ return NFC_STATUS_FAILED;
+ }
/* a valid opcode for RW - remove */
p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
if (p_data) {
diff --git a/src/nfc/tags/rw_t3t.cc b/src/nfc/tags/rw_t3t.cc
index 0f1c8b4..58b84fd 100644
--- a/src/nfc/tags/rw_t3t.cc
+++ b/src/nfc/tags/rw_t3t.cc
@@ -1207,6 +1207,12 @@
uint8_t* p;
tNFC_STATUS retval = NFC_STATUS_OK;
+ /* GKI_BUF2 is used for NFC_RW_POOL */
+ if (len > GKI_BUF2_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - 2) {
+ android_errorWriteLog(0x534e4554, "157649467");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
p_cmd_buf = rw_t3t_get_cmd_buf();
if (p_cmd_buf != nullptr) {
/* Construct T3T message */