Merge branch 'feat/sec_esp_drivers_v5.2' into 'release/v5.2'

fix(drivers): harden multiple peripheral drivers against local DoS and memory corruption (v5.2)

See merge request espressif/esp-idf!50562
This commit is contained in:
morris
2026-07-29 16:59:14 +08:00
5 changed files with 33 additions and 11 deletions

View File

@@ -119,21 +119,28 @@ esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_
esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus)
{
esp_err_t ret = ESP_OK;
int port_num = i2c_bus->port_num;
i2c_clock_source_t clk_src = i2c_bus->clk_src;
bool do_deinitialize = false;
_lock_acquire(&s_i2c_platform.mutex);
if (s_i2c_platform.buses[port_num]) {
s_i2c_platform.count[port_num]--;
if (s_i2c_platform.count[port_num] == 0) {
if (s_i2c_platform.count[port_num] > 1) {
s_i2c_platform.count[port_num]--;
} else {
do_deinitialize = true;
s_i2c_platform.buses[port_num] = NULL;
if (i2c_bus->intr_handle) {
ESP_RETURN_ON_ERROR(esp_intr_free(i2c_bus->intr_handle), TAG, "delete interrupt service failed");
ESP_GOTO_ON_ERROR(esp_intr_free(i2c_bus->intr_handle), err, TAG, "delete interrupt service failed");
i2c_bus->intr_handle = NULL;
}
#if CONFIG_PM_ENABLE
if (i2c_bus->pm_lock) {
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(i2c_bus->pm_lock), TAG, "delete pm_lock failed");
esp_pm_lock_delete(i2c_bus->pm_lock);
i2c_bus->pm_lock = NULL;
}
#endif
s_i2c_platform.count[port_num] = 0;
s_i2c_platform.buses[port_num] = NULL;
// Disable I2C module
I2C_RCC_ATOMIC() {
i2c_ll_enable_bus_clock(port_num, false);
@@ -156,9 +163,11 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus)
if (do_deinitialize) {
ESP_LOGD(TAG, "delete bus %d", port_num);
}
ESP_RETURN_ON_FALSE(s_i2c_platform.count[port_num] == 0, ESP_ERR_INVALID_STATE, TAG, "Bus not freed entirely");
return ESP_OK;
err:
_lock_release(&s_i2c_platform.mutex);
return ret;
}
esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, i2c_clock_source_t clk_src)

View File

@@ -760,7 +760,12 @@ static esp_err_t start_command_read_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cm
}
// Arrange RX buffer
size_t will_receive = MIN(rx_length, SDSPI_MAX_DATA_LEN) - extra_data_size;
size_t expected_data_size = MIN(rx_length, SDSPI_MAX_DATA_LEN);
if (extra_data_size > expected_data_size) {
ESP_LOGD(TAG, "%s: invalid extra data size %u (expected <= %u)", __func__, (unsigned)extra_data_size, (unsigned)expected_data_size);
return ESP_ERR_INVALID_RESPONSE;
}
size_t will_receive = expected_data_size - extra_data_size;
uint8_t* rx_data;
ret = get_block_buf(slot, &rx_data);
if (ret != ESP_OK) {

View File

@@ -219,6 +219,7 @@ static esp_err_t check_valid(const adc_cali_curve_fitting_config_t *config)
{
ESP_RETURN_ON_FALSE(config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC unit");
ESP_RETURN_ON_FALSE(config->atten < SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC attenuation");
ESP_RETURN_ON_FALSE(config->chan < SOC_ADC_CHANNEL_NUM(config->unit_id), ESP_ERR_INVALID_ARG, TAG, "invalid ADC channel");
bool available_oneshot_bitwidth = (config->bitwidth >= SOC_ADC_RTC_MIN_BITWIDTH && config->bitwidth <= SOC_ADC_RTC_MAX_BITWIDTH);
bool available_dma_bitwidth = (config->bitwidth >= SOC_ADC_DIGI_MIN_BITWIDTH && config->bitwidth <= SOC_ADC_DIGI_MAX_BITWIDTH);

View File

@@ -78,11 +78,15 @@ static esp_err_t s_adc_filter_claim(adc_continuous_handle_t handle, adc_iir_filt
static esp_err_t s_adc_filter_free(adc_iir_filter_t *filter_ctx)
{
assert(filter_ctx);
esp_err_t ret = ESP_ERR_NOT_FOUND;
portENTER_CRITICAL(&s_filter_spinlock);
filter_ctx->continuous_ctx->iir_filter[filter_ctx->filter_id] = NULL;
if (filter_ctx->continuous_ctx->iir_filter[filter_ctx->filter_id] != NULL) {
filter_ctx->continuous_ctx->iir_filter[filter_ctx->filter_id] = NULL;
ret = ESP_OK;
}
portEXIT_CRITICAL(&s_filter_spinlock);
return ESP_OK;
return ret;
}
#endif

View File

@@ -154,7 +154,7 @@ typedef struct {
esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config_t *config, adc_cali_handle_t *ret_handle)
{
esp_err_t ret = ESP_OK;
ESP_RETURN_ON_FALSE(config && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC unit");
ESP_RETURN_ON_FALSE(config->atten < SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC attenuation");
ESP_RETURN_ON_FALSE(((config->bitwidth >= SOC_ADC_RTC_MIN_BITWIDTH && config->bitwidth <= SOC_ADC_RTC_MAX_BITWIDTH) || config->bitwidth == ADC_BITWIDTH_DEFAULT), ESP_ERR_INVALID_ARG, TAG, "invalid bitwidth");
@@ -204,6 +204,9 @@ esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config
return ESP_OK;
err:
if (chars) {
free(chars);
}
if (scheme) {
free(scheme);
}