fix(openthread): fix null pointer deref, uninitialized struct, and unbounded strcpy in spinel/RCP code

This commit is contained in:
zwx
2026-09-08 14:58:15 +08:00
parent 2c480d92fa
commit 36b1759428
4 changed files with 20 additions and 8 deletions
@@ -414,7 +414,8 @@ esp_err_t esp_radio_spinel_rcp_deinit(esp_radio_spinel_idx_t idx);
/**
* @brief Get the version of RCP.
*
* @param[in] running_rcp_version A pointer to the RCP version string.
* @param[in] running_rcp_version A pointer to a caller-allocated buffer of at least 128 bytes,
* to be filled with the null-terminated RCP version string.
* @param[in] idx The index of 802.15.4 related protocol stack.
*
* @return
@@ -199,6 +199,10 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
int32_t pending_mode = 0;
mDecoder.ReadInt32(pending_mode);
if (pending_mode < ESP_IEEE802154_AUTO_PENDING_DISABLE || pending_mode > ESP_IEEE802154_AUTO_PENDING_ZIGBEE) {
error = OT_ERROR_INVALID_ARGS;
break;
}
esp_ieee802154_set_pending_mode(static_cast<esp_ieee802154_pending_mode_t>(pending_mode));
break;
}
@@ -135,14 +135,16 @@ err:
void esp_openthread_spi_slave_deinit(void)
{
spi_slave_free(s_spi_config->host_device);
s_spi_config->slave_config.post_setup_cb = NULL;
s_spi_config->slave_config.post_trans_cb = NULL;
heap_caps_free(s_spi_config);
if (s_spi_config != NULL) {
spi_slave_free(s_spi_config->host_device);
s_spi_config->slave_config.post_setup_cb = NULL;
s_spi_config->slave_config.post_trans_cb = NULL;
heap_caps_free(s_spi_config);
s_spi_config = NULL;
}
heap_caps_free(s_spi_transaction);
heap_caps_free(s_pending_transaction);
heap_caps_free(s_rx_dma_buf);
s_spi_config = NULL;
s_spi_transaction = NULL;
s_pending_transaction = NULL;
s_rx_dma_buf = NULL;
@@ -134,7 +134,7 @@ void TransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAc
uint8_t *frame = (uint8_t *)calloc(1, aFrame->mLength + 1);
uint8_t *ack = nullptr;
if (frame) {
esp_ieee802154_frame_info_t ack_info;
esp_ieee802154_frame_info_t ack_info = {};
frame[0] = aFrame->mLength;
memcpy((void *)(frame + 1), aFrame->mPsdu, frame[0]);
if (aAckFrame) {
@@ -142,6 +142,11 @@ void TransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAc
if (ack) {
ack[0] = aAckFrame->mLength;
memcpy((void *)(ack + 1), aAckFrame->mPsdu, ack[0]);
ack_info.rssi = aAckFrame->mInfo.mRxInfo.mRssi;
ack_info.channel = aAckFrame->mChannel;
ack_info.lqi = aAckFrame->mInfo.mRxInfo.mLqi;
ack_info.timestamp = aAckFrame->mInfo.mRxInfo.mTimestamp;
ack_info.pending = aAckFrame->mInfo.mRxInfo.mAckedWithFramePending;
} else {
ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to alloc memory for ack");
}
@@ -404,7 +409,7 @@ esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_
{
const char *rcp_version = s_radio[idx].GetVersion();
ESP_RETURN_ON_FALSE(rcp_version != nullptr, ESP_FAIL, ESP_SPINEL_LOG_TAG, "Fail to get rcp version");
strcpy(running_rcp_version, rcp_version);
strlcpy(running_rcp_version, rcp_version, ESP_RADIO_SPINEL_RCP_VERSION_MAX_SIZE);
return ESP_OK;
}