Prevent OOB read in phNxpNciHal_core_initialized Bug: 153731335 Bug: 153731369 Bug: 153731880 Test: NFC on/off Change-Id: Ie128e8b18d2b037739568140df17e9eb888decb1
diff --git a/1.1/Nfc.cpp b/1.1/Nfc.cpp index 9954c1f..d4a4eb7 100755 --- a/1.1/Nfc.cpp +++ b/1.1/Nfc.cpp
@@ -72,7 +72,7 @@ Return<V1_0::NfcStatus> Nfc::coreInitialized(const hidl_vec<uint8_t>& data) { hidl_vec<uint8_t> copy = data; - NFCSTATUS status = phNxpNciHal_core_initialized(©[0]); + NFCSTATUS status = phNxpNciHal_core_initialized(copy.size(), ©[0]); return CHK_STATUS(status); }
diff --git a/1.2/Nfc.cpp b/1.2/Nfc.cpp index 540f982..bf1095b 100755 --- a/1.2/Nfc.cpp +++ b/1.2/Nfc.cpp
@@ -71,7 +71,7 @@ Return<V1_0::NfcStatus> Nfc::coreInitialized(const hidl_vec<uint8_t>& data) { hidl_vec<uint8_t> copy = data; - NFCSTATUS status = phNxpNciHal_core_initialized(©[0]); + NFCSTATUS status = phNxpNciHal_core_initialized(copy.size(), ©[0]); return CHK_STATUS(status); }
diff --git a/halimpl/hal/phNxpNciHal.cc b/halimpl/hal/phNxpNciHal.cc index f9a482d..6b4b748 100644 --- a/halimpl/hal/phNxpNciHal.cc +++ b/halimpl/hal/phNxpNciHal.cc
@@ -1237,7 +1237,7 @@ * Returns Always returns NFCSTATUS_SUCCESS (0). * ******************************************************************************/ -int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) { +int phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len, uint8_t* p_core_init_rsp_params) { NFCSTATUS status = NFCSTATUS_SUCCESS; static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x05}; @@ -1277,7 +1277,8 @@ if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { return NFCSTATUS_FAILED; } - if ((*p_core_init_rsp_params > 0) && + if (core_init_rsp_params_len >= 1 && + (*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) // initializing for recovery. { retry_core_init: @@ -1711,7 +1712,8 @@ config_access = false; // if recovery mode and length of last command is 0 then only reset the P2P // listen mode routing. - if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) && + if (core_init_rsp_params_len >= 36 && + (*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) && p_core_init_rsp_params[35] == 0) { /* P2P listen mode routing */ status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd), @@ -1773,7 +1775,8 @@ } } - if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) { + if (core_init_rsp_params_len >= 1 && + (*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) { static phLibNfc_Message_t msg; uint16_t tmp_len = 0; uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01}; @@ -1812,7 +1815,8 @@ goto retry_core_init; } - if (*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!! + if (core_init_rsp_params_len >= 4 && + *(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!! { NXPLOG_NCIHAL_W("Sending Set Screen ON State Command as raw packet!!"); status = @@ -1824,6 +1828,9 @@ goto retry_core_init; } + if (p_core_init_rsp_params[2] > (core_init_rsp_params_len - 3)) { + return NFCSTATUS_FAILED; + } NXPLOG_NCIHAL_W("Sending discovery as raw packet!!"); status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2], (uint8_t*)&p_core_init_rsp_params[3]); @@ -1847,7 +1854,8 @@ } NXPLOG_NCIHAL_W("Sending last command for Recovery "); - if (p_core_init_rsp_params[35] > 0) { // if length of last command is 0 + if (core_init_rsp_params_len >= 40 && + p_core_init_rsp_params[35] > 0) { // if length of last command is 0 // then it doesn't need to send last // command. if (!(((p_core_init_rsp_params[36] == 0x21) && @@ -1884,7 +1892,9 @@ } p_core_init_rsp_params[35] = (uint8_t)tmp_len; - + if (p_core_init_rsp_params[35] > (core_init_rsp_params_len - 36)) { + return NFCSTATUS_FAILED; + } status = phNxpNciHal_send_ext_cmd( p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]); if (status != NFCSTATUS_SUCCESS) { @@ -1905,13 +1915,14 @@ // initialize dummy FW recovery variables gRecFWDwnld = 0; gRecFwRetryCount = 0; - if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))) + if (core_init_rsp_params_len >= 1 && + !((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))) phNxpNciHal_core_initialized_complete(status); else { invoke_callback: config_access = false; if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) { - *p_core_init_rsp_params = 0; + if (core_init_rsp_params_len) *p_core_init_rsp_params = 0; NXPLOG_NCIHAL_W("Invoking data callback!!"); (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
diff --git a/halimpl/inc/phNxpNciHal_Adaptation.h b/halimpl/inc/phNxpNciHal_Adaptation.h index 8f5da81..4a0a165 100644 --- a/halimpl/inc/phNxpNciHal_Adaptation.h +++ b/halimpl/inc/phNxpNciHal_Adaptation.h
@@ -35,7 +35,7 @@ int phNxpNciHal_MinOpen(); int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data); int phNxpNciHal_write_internal(uint16_t data_len, const uint8_t* p_data); -int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params); +int phNxpNciHal_core_initialized(uint16_t core_init_rsp_len, uint8_t* p_core_init_rsp_params); int phNxpNciHal_pre_discover(void); int phNxpNciHal_close(bool); int phNxpNciHal_configDiscShutdown(void);