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

This commit is contained in:
zwx
2026-07-02 15:31:46 +08:00
committed by Zhang Wen Xu
parent 6a9c44fe7e
commit 4b29feab5d
4 changed files with 22 additions and 8 deletions

View File

@@ -384,7 +384,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

View File

@@ -179,6 +179,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;
}

View File

@@ -121,13 +121,15 @@ 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);
s_spi_config = NULL;
s_spi_transaction = NULL;
s_pending_transaction = NULL;
return;

View File

@@ -19,6 +19,8 @@
#define SPINEL_VENDOR_PROPERTY_BIT_PENDINGMODE BIT(0)
#define SPINEL_VENDOR_PROPERTY_BIT_COORDINATOR BIT(1)
// Must match ot::Spinel::SpinelDriver::kVersionStringSize (private, spinel_driver.hpp).
#define ESP_RADIO_SPINEL_RCP_VERSION_MAX_SIZE 128
static esp_ieee802154_pending_mode_t s_spinel_vendor_property_pendingmode[ot::Spinel::kSpinelHeaderMaxNumIid] = {ESP_IEEE802154_AUTO_PENDING_DISABLE};
static bool s_spinel_vendor_property_coordinator[ot::Spinel::kSpinelHeaderMaxNumIid] = {false};
static uint64_t s_spinel_vendor_property_mask[ot::Spinel::kSpinelHeaderMaxNumIid] = {0};
@@ -126,7 +128,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) {
@@ -134,6 +136,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");
}
@@ -375,7 +382,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;
}