mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'feat/sec_esp_drivers_v5.4' into 'release/v5.4'
fix(drivers): harden multiple peripheral drivers against local DoS and memory corruption (v5.4) See merge request espressif/esp-idf!50559
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
||||
free(ctlr);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "no available csi controller");
|
||||
}
|
||||
ctlr->csi_fsm = CSI_FSM_INIT;
|
||||
|
||||
ESP_LOGD(TAG, "config->queue_items: %d", config->queue_items);
|
||||
ctlr->trans_que = xQueueCreateWithCaps(config->queue_items, sizeof(esp_cam_ctlr_trans_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
@@ -213,7 +214,6 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
||||
ESP_GOTO_ON_ERROR(dw_gdma_channel_register_event_callbacks(csi_dma_chan, &csi_dma_cbs, ctlr), err, TAG, "failed to register dwgdma callback");
|
||||
|
||||
ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
ctlr->csi_fsm = CSI_FSM_INIT;
|
||||
ctlr->base.del = s_ctlr_del;
|
||||
ctlr->base.enable = s_csi_ctlr_enable;
|
||||
ctlr->base.start = s_ctlr_csi_start;
|
||||
@@ -258,7 +258,9 @@ esp_err_t s_del_csi_ctlr(csi_controller_t *ctlr)
|
||||
if (!ctlr->bk_buffer_dis) {
|
||||
free(ctlr->backup_buffer);
|
||||
}
|
||||
vQueueDeleteWithCaps(ctlr->trans_que);
|
||||
if (ctlr->trans_que) {
|
||||
vQueueDeleteWithCaps(ctlr->trans_que);
|
||||
}
|
||||
free(ctlr);
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
@@ -190,15 +190,24 @@ 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_GOTO_ON_ERROR(esp_intr_free(i2c_bus->intr_handle), err, TAG, "delete interrupt service failed");
|
||||
i2c_bus->intr_handle = NULL;
|
||||
}
|
||||
if (i2c_bus->pm_lock) {
|
||||
esp_pm_lock_delete(i2c_bus->pm_lock);
|
||||
i2c_bus->pm_lock = NULL;
|
||||
}
|
||||
#if I2C_USE_RETENTION_LINK
|
||||
if (i2c_bus->is_lp_i2c == false) {
|
||||
if (i2c_bus->retention_link_created) {
|
||||
@@ -207,12 +216,8 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus)
|
||||
sleep_retention_module_deinit(i2c_regs_retention[port_num].module_id);
|
||||
}
|
||||
#endif
|
||||
if (i2c_bus->intr_handle) {
|
||||
ESP_RETURN_ON_ERROR(esp_intr_free(i2c_bus->intr_handle), TAG, "delete interrupt service failed");
|
||||
}
|
||||
if (i2c_bus->pm_lock) {
|
||||
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(i2c_bus->pm_lock), TAG, "delete pm_lock failed");
|
||||
}
|
||||
s_i2c_platform.count[port_num] = 0;
|
||||
s_i2c_platform.buses[port_num] = NULL;
|
||||
// Disable I2C module
|
||||
if (!i2c_bus->is_lp_i2c) {
|
||||
I2C_RCC_ATOMIC() {
|
||||
@@ -244,9 +249,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, soc_module_clk_t clk_src)
|
||||
|
||||
@@ -863,11 +863,12 @@ static esp_err_t i2c_master_bus_destroy(i2c_master_bus_handle_t bus_handle)
|
||||
}
|
||||
bus_handle = NULL;
|
||||
}
|
||||
|
||||
free(i2c_master);
|
||||
} else {
|
||||
free(i2c_master);
|
||||
// Non-OK here means interrupt teardown did not complete, so the ISR
|
||||
// may still reference i2c_slave and its wrapper-owned resources.
|
||||
return err;
|
||||
}
|
||||
free(i2c_master);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -212,6 +212,11 @@ static esp_err_t i2c_slave_device_destroy(i2c_slave_dev_handle_t i2c_slave)
|
||||
i2c_ll_disable_intr_mask(i2c_slave->base->hal.dev, I2C_LL_SLAVE_EVENT_INTR);
|
||||
i2c_common_deinit_pins(i2c_slave->base);
|
||||
ret = i2c_release_bus_handle(i2c_slave->base);
|
||||
if (ret != ESP_OK) {
|
||||
// Non-OK here means interrupt teardown did not complete, so the ISR
|
||||
// may still reference i2c_slave and its wrapper-owned resources.
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (i2c_slave->rx_ring_buf) {
|
||||
vRingbufferDeleteWithCaps(i2c_slave->rx_ring_buf);
|
||||
|
||||
@@ -40,6 +40,7 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec)
|
||||
#endif
|
||||
esp_err_t ret = ESP_OK;
|
||||
bool new_codec = false;
|
||||
bool bus_clock_enabled = false;
|
||||
jpeg_codec_t *codec = NULL;
|
||||
_lock_acquire(&s_jpeg_platform.mutex);
|
||||
if (!s_jpeg_platform.jpeg_codec) {
|
||||
@@ -50,7 +51,7 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec)
|
||||
codec->intr_priority = -1;
|
||||
codec->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
codec->codec_mutex = xSemaphoreCreateBinaryWithCaps(JPEG_MEM_ALLOC_CAPS);
|
||||
ESP_RETURN_ON_FALSE(codec->codec_mutex, ESP_ERR_NO_MEM, TAG, "No memory for codec mutex");
|
||||
ESP_GOTO_ON_FALSE(codec->codec_mutex, ESP_ERR_NO_MEM, err, TAG, "No memory for codec mutex");
|
||||
SLIST_INIT(&codec->jpeg_isr_handler_list);
|
||||
xSemaphoreGive(codec->codec_mutex);
|
||||
// init the clock
|
||||
@@ -58,8 +59,10 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec)
|
||||
jpeg_ll_enable_bus_clock(true);
|
||||
jpeg_ll_reset_module_register();
|
||||
}
|
||||
bus_clock_enabled = true;
|
||||
#if CONFIG_PM_ENABLE
|
||||
ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "jpeg_codec", &codec->pm_lock), TAG, "create pm lock failed");
|
||||
ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "jpeg_codec", &codec->pm_lock),
|
||||
err, TAG, "create pm lock failed");
|
||||
#endif
|
||||
jpeg_hal_init(&codec->hal);
|
||||
} else {
|
||||
@@ -78,6 +81,27 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec)
|
||||
*jpeg_new_codec = s_jpeg_platform.jpeg_codec;
|
||||
_lock_release(&s_jpeg_platform.mutex);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (codec) {
|
||||
if (codec->codec_mutex) {
|
||||
vSemaphoreDeleteWithCaps(codec->codec_mutex);
|
||||
}
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (codec->pm_lock) {
|
||||
esp_pm_lock_delete(codec->pm_lock);
|
||||
}
|
||||
#endif
|
||||
if (bus_clock_enabled) {
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
jpeg_ll_enable_bus_clock(false);
|
||||
}
|
||||
}
|
||||
free(codec);
|
||||
}
|
||||
s_jpeg_platform.jpeg_codec = NULL;
|
||||
_lock_release(&s_jpeg_platform.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t jpeg_release_codec_handle(jpeg_codec_handle_t jpeg_codec)
|
||||
|
||||
@@ -809,7 +809,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) {
|
||||
|
||||
@@ -402,6 +402,7 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi
|
||||
|
||||
r = xQueueSend(spihost[host]->trans_queue, (void *)&priv_trans, ticks_to_wait);
|
||||
if (!r) {
|
||||
spi_slave_uninstall_priv_trans(host, &priv_trans);
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
esp_intr_enable(spihost[host]->intr);
|
||||
|
||||
Reference in New Issue
Block a user