Skip to content

Commit

Permalink
Fix double free of esp32 uart driver on close
Browse files Browse the repository at this point in the history
- Also fix usage of memory_ensure_free in esp32 uart driver
- Also remove unnecessary condition in context_destroy

Signed-off-by: Paul Guyot <pguyot@kallisys.net>
  • Loading branch information
pguyot committed Jan 5, 2025
1 parent dfc3bf1 commit af80836
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ certain VM instructions are used.
- Fixed an issue where a timeout would occur immediately in a race condition
- Fixed SPI close command
- Added missing lock on socket structure
- Fixed a double free when esp32 uart driver was closed, yielding an assert abort

## [0.6.5] - 2024-10-15

Expand Down
4 changes: 1 addition & 3 deletions src/libAtomVM/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ void context_destroy(Context *ctx)
// globalcontext_get_process_lock before accessing platform_data.
// Here, the context can no longer be acquired with
// globalcontext_get_process_lock, so it's safe to free the pointer.
if (ctx->platform_data) {
free(ctx->platform_data);
}
free(ctx->platform_data);

free(ctx);
}
Expand Down
9 changes: 5 additions & 4 deletions src/platforms/esp32/components/avm_builtins/uart_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ static void uart_driver_do_read(Context *ctx, GenMessage gen_message)
int local_pid = term_to_local_process_id(pid);

if (uart_data->reader_process_pid != term_invalid_term()) {
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2) * 2 + REF_SIZE) != MEMORY_GC_OK)) {
if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2) * 2 , 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
ESP_LOGE(TAG, "[uart_driver_do_read] Failed to allocate space for error tuple");
globalcontext_send_message(glb, local_pid, MEMORY_ATOM);
return;
Expand All @@ -326,7 +326,7 @@ static void uart_driver_do_read(Context *ctx, GenMessage gen_message)

if (count > 0) {
int bin_size = term_binary_heap_size(count);
if (UNLIKELY(memory_ensure_free(ctx, bin_size + TUPLE_SIZE(2) * 2 + REF_SIZE) != MEMORY_GC_OK)) {
if (UNLIKELY(memory_ensure_free_with_roots(ctx, bin_size + TUPLE_SIZE(2) * 2, 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
ESP_LOGE(TAG, "[uart_driver_do_read] Failed to allocate space for return value");
globalcontext_send_message(glb, local_pid, MEMORY_ATOM);
}
Expand Down Expand Up @@ -387,7 +387,7 @@ static void uart_driver_do_write(Context *ctx, GenMessage gen_message)
free(buffer);

int local_pid = term_to_local_process_id(pid);
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2) + REF_SIZE) != MEMORY_GC_OK)) {
if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
ESP_LOGE(TAG, "[uart_driver_do_write] Failed to allocate space for return value");
globalcontext_send_message(glb, local_pid, MEMORY_ATOM);
}
Expand All @@ -406,7 +406,7 @@ static void uart_driver_do_close(Context *ctx, GenMessage gen_message)

sys_unregister_listener(glb, &uart_data->listener);

if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2) + REF_SIZE) != MEMORY_GC_OK)) {
if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
ESP_LOGE(TAG, "[uart_driver_do_close] Failed to allocate space for return value");
globalcontext_send_message(glb, local_pid, MEMORY_ATOM);
}
Expand All @@ -419,6 +419,7 @@ static void uart_driver_do_close(Context *ctx, GenMessage gen_message)
}

free(uart_data);
ctx->platform_data = NULL;
}

static NativeHandlerResult uart_driver_consume_mailbox(Context *ctx)
Expand Down

0 comments on commit af80836

Please sign in to comment.