mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'backport-50410-to-release/v6.1' into 'release/v6.1'
fix(pthread,ulp): harden TLS key lookup and ULP bss_size validation (v6.1) See merge request espressif/esp-idf!50956
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -72,17 +72,21 @@ int pthread_key_create(pthread_key_t *key, pthread_destructor_t destructor)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static key_entry_t *find_key(pthread_key_t key)
|
static bool lookup_key(pthread_key_t key, pthread_destructor_t *destructor_out)
|
||||||
{
|
{
|
||||||
portENTER_CRITICAL(&s_keys_lock);
|
portENTER_CRITICAL(&s_keys_lock);
|
||||||
key_entry_t *result = NULL;;
|
key_entry_t *entry;
|
||||||
SLIST_FOREACH(result, &s_keys, next) {
|
SLIST_FOREACH(entry, &s_keys, next) {
|
||||||
if (result->key == key) {
|
if (entry->key == key) {
|
||||||
break;
|
if (destructor_out != NULL) {
|
||||||
|
*destructor_out = entry->destructor;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&s_keys_lock);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&s_keys_lock);
|
portEXIT_CRITICAL(&s_keys_lock);
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pthread_key_delete(pthread_key_t key)
|
int pthread_key_delete(pthread_key_t key)
|
||||||
@@ -94,7 +98,12 @@ int pthread_key_delete(pthread_key_t key)
|
|||||||
and delete any values associated with this key. We do not do this...
|
and delete any values associated with this key. We do not do this...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
key_entry_t *entry = find_key(key);
|
key_entry_t *entry = NULL;
|
||||||
|
SLIST_FOREACH(entry, &s_keys, next) {
|
||||||
|
if (entry->key == key) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
SLIST_REMOVE(&s_keys, entry, key_entry_t_, next);
|
SLIST_REMOVE(&s_keys, entry, key_entry_t_, next);
|
||||||
free(entry);
|
free(entry);
|
||||||
@@ -138,9 +147,9 @@ static void pthread_cleanup_thread_specific_data_callback(int index, void *v_tls
|
|||||||
// This is a little slow, walking the linked list of keys once per value,
|
// This is a little slow, walking the linked list of keys once per value,
|
||||||
// but assumes that the thread's value list will have less entries
|
// but assumes that the thread's value list will have less entries
|
||||||
// than the keys list
|
// than the keys list
|
||||||
key_entry_t *key = find_key(entry->key);
|
pthread_destructor_t destructor = NULL;
|
||||||
if (key != NULL && key->destructor != NULL) {
|
if (lookup_key(entry->key, &destructor) && destructor != NULL) {
|
||||||
key->destructor(entry->value);
|
destructor(entry->value);
|
||||||
}
|
}
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
@@ -196,8 +205,7 @@ void *pthread_getspecific(pthread_key_t key)
|
|||||||
|
|
||||||
int pthread_setspecific(pthread_key_t key, const void *value)
|
int pthread_setspecific(pthread_key_t key, const void *value)
|
||||||
{
|
{
|
||||||
key_entry_t *key_entry = find_key(key);
|
if (!lookup_key(key, NULL)) {
|
||||||
if (key_entry == NULL) {
|
|
||||||
return ENOENT; // this situation is undefined by pthreads standard
|
return ENOENT; // this situation is undefined by pthreads standard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* prog
|
|||||||
* @return
|
* @return
|
||||||
* - ESP_OK on success
|
* - ESP_OK on success
|
||||||
* - ESP_ERR_INVALID_ARG if load_addr is out of range
|
* - ESP_ERR_INVALID_ARG if load_addr is out of range
|
||||||
* - ESP_ERR_INVALID_SIZE if program_size doesn't match (TEXT_OFFSET + TEXT_SIZE + DATA_SIZE)
|
* - ESP_ERR_INVALID_SIZE if program_size doesn't match (TEXT_OFFSET + TEXT_SIZE + DATA_SIZE),
|
||||||
|
* or if TEXT_SIZE + DATA_SIZE + BSS_SIZE exceeds the reserved ULP memory region
|
||||||
* - ESP_ERR_NOT_SUPPORTED if the magic number is incorrect
|
* - ESP_ERR_NOT_SUPPORTED if the magic number is incorrect
|
||||||
*/
|
*/
|
||||||
esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, size_t program_size);
|
esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, size_t program_size);
|
||||||
|
|||||||
@@ -154,6 +154,13 @@ esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t text_data_size = header.text_size + header.data_size;
|
size_t text_data_size = header.text_size + header.data_size;
|
||||||
|
if (text_data_size > CONFIG_ULP_COPROC_RESERVE_MEM - load_addr_bytes) {
|
||||||
|
return ESP_ERR_INVALID_SIZE;
|
||||||
|
}
|
||||||
|
if ((size_t) header.bss_size > CONFIG_ULP_COPROC_RESERVE_MEM - load_addr_bytes - text_data_size) {
|
||||||
|
return ESP_ERR_INVALID_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* base = (uint8_t*) RTC_SLOW_MEM;
|
uint8_t* base = (uint8_t*) RTC_SLOW_MEM;
|
||||||
|
|
||||||
memcpy(base + load_addr_bytes, program_binary + header.text_offset, text_data_size);
|
memcpy(base + load_addr_bytes, program_binary + header.text_offset, text_data_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user