2023.09.19
CVE-2022-20447 | A-233604485 | ID | High | 13 |
---|
patch

分析
在BNEP_WriteBuf -> bnepu_check_send_packet
中,是有场景可能导致p_buf
被释放的,但是在从PAN_WriteBuf
开始的调用链里,并没有对其做这种情况做检验。最后在[5]处的pcb->write.octets += p_buf->len
可能导致UAF。
patch是把UAF的Use给消除掉,即在调用BNEP_WriteBuf
之前,先把p_buf->len
给拿出来赋值给局部变量len,那么后面给pcb->write.octets
赋值的时候使用局部变量就不会产生UAF了。
诶,那么搜一下BNEP_WriteBuf
,看看调用它的地方还有没有类似的问题,可惜的是就两处,并没有类似的问题。
- PAN_WriteBuf
// system/stack/pan/pan_api.cc
/*******************************************************************************
*
* Function PAN_WriteBuf
*
* Description This sends data over the PAN connections. If this is called
* on GN or NAP side and the packet is multicast or broadcast
* it will be sent on all the links. Otherwise the correct link
* is found based on the destination address and forwarded on
* it. If the return value is not PAN_SUCCESS, the application
* should take care of releasing the message buffer.
*
* Parameters: handle - handle for the connection
* dst - MAC or BD Addr of the destination device
* src - MAC or BD Addr of the source who sent this packet
* protocol - protocol of the ethernet packet like IP or ARP
* p_buf - pointer to the data buffer
* ext - to indicate that extension headers present
*
* Returns PAN_SUCCESS - if the data is sent successfully
* PAN_FAILURE - if the connection is not found or
* there is an error in sending data
*
******************************************************************************/
tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
const RawAddress& src, uint16_t protocol,
BT_HDR* p_buf, bool ext) {
......
// [1] 调用BNEP_WriteBuf,传入p_buf
result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, &src, ext);
if (result == BNEP_IGNORE_CMD) {
PAN_TRACE_DEBUG("PAN ignored data buf write to PANU");
pcb->write.errors++;
return PAN_IGNORE_CMD;
} else if (result != BNEP_SUCCESS) {
PAN_TRACE_ERROR("PAN failed to send data buf to the PANU");
pcb->write.errors++;
return (tPAN_RESULT)result;
}
pcb->write.octets += p_buf->len; // [5] 在BNEP_WriteBuf中,p_buf可能已经释放了,这里仍然使用,可能造成UAF
pcb->write.packets++;
PAN_TRACE_DEBUG("PAN successfully sent data buf to the PANU");
return PAN_SUCCESS;
}
BNEP_WriteBuf
// system/stack/bnep/bnep_api.cc
tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr,
BT_HDR* p_buf, uint16_t protocol,
const RawAddress* p_src_addr, bool fw_ext_present) {
......
/* Send the data or queue it up */
bnepu_check_send_packet(p_bcb, p_buf); // [2] 调用bnepu_check_send_packet,传入p_buf
return (BNEP_SUCCESS); // [4] 没有对bnepu_check_send_packet中释放p_buf的情况做检查,直接返回BNEP_SUCCESS
}
bnepu_check_send_packet
// system/stack/bnep/bnep_utils.cc
/*******************************************************************************
*
* Function bnepu_check_send_packet
*
* Description This function tries to send a packet to L2CAP.
* If L2CAP is flow controlled, it enqueues the
* packet to the transmit queue
*
* Returns void
*
******************************************************************************/
void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) {
LOG_DEBUG("BNEP - bnepu_check_send_packet for CID: 0x%x", p_bcb->l2cap_cid);
if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED) {
if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
LOG_WARN("BNEP - congested, dropping buf, CID: 0x%x", p_bcb->l2cap_cid);
osi_free(p_buf); // [3] 满足上述条件时,会释放p_buf
} else {
fixed_queue_enqueue(p_bcb->xmit_q, p_buf);
}
} else {
L2CA_DataWrite(p_bcb->l2cap_cid, p_buf);
}
}