Skip to content

Commit f8eba15

Browse files
committed
[bug]: Fix use-after-free in ephemeral_bridging_function after a bad merge.
- Restore correct ownership transfer in EventBridge.cpp by reintroducing local_bridge, ensuring doWork() is called on a valid object and preventing use-after-free. - Minor doc and formatting updates, Signed-off-by: Goran Mišković <schkovich@users.noreply.github.com>
1 parent e79fd15 commit f8eba15

File tree

5 files changed

+21
-16
lines changed

5 files changed

+21
-16
lines changed

include/TcpClientContext.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ namespace async_tcp {
581581
}
582582

583583
void setOnErrorCallback(const std::function<void(err_t err)> &cb) {
584-
_errorCb = cb; // Set the error callback
584+
_errorCb = cb;
585585
}
586586

587587
void setOnReceiveCallback(

include/TcpWriteHandler.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "TcpClient.hpp"
2121
#include <functional>
2222
#include <memory>
23-
#include <string>
2423

2524
namespace async_tcp {
2625

@@ -71,7 +70,6 @@ namespace async_tcp {
7170
* @param ctx Context manager for execution
7271
* @param data Pointer to binary data chunk to write
7372
* @param size Size of data chunk to write
74-
* @param remaining Total remaining bytes to write (including this chunk)
7573
* @param io TCP client to use
7674
*/
7775
static void create(const AsyncCtx & ctx,

src/EventBridge.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@
33
* @brief Implementation of the EventBridge class for bridging between C-style
44
* async context and C++ event handling.
55
*
6-
* This file implements the EventBridge class, which provides a foundation for event handlers with proper core affinity in the AsyncTcpClient library.
7-
* It supports explicit initialization and registration of worker types:
6+
* This file implements the EventBridge class, which provides a foundation for
7+
* event handlers with proper core affinity in the AsyncTcpClient library. It
8+
* supports explicit initialization and registration of worker types:
89
*
9-
* 1. Persistent "when pending" workers - Registered via initialisePerpetualBridge().
10-
* These remain registered with the context manager until explicitly removed. Registration is no longer automatic in the constructor.
10+
* 1. Persistent "when pending" workers - Registered via
11+
* initialisePerpetualBridge(). These remain registered with the context manager
12+
* until explicitly removed. Registration is no longer automatic in the
13+
* constructor.
1114
*
1215
* 2. Ephemeral "at time" workers - Registered via initialiseEphemeralBridge().
13-
* These execute once at a specific time and are automatically removed from the context manager after execution. They can optionally manage their own lifecycle through self-ownership.
16+
* These execute once at a specific time and are automatically removed from
17+
* the context manager after execution. They can optionally manage their own
18+
* lifecycle through self-ownership.
1419
*
15-
* The implementation manages worker registration, lifecycle, and event execution, following the Template Method pattern. It provides thread-safe execution with core affinity guarantees and a clean separation between async mechanisms and business logic.
20+
* The implementation manages worker registration, lifecycle, and event
21+
* execution, following the Template Method pattern. It provides thread-safe
22+
* execution with core affinity guarantees and a clean separation between async
23+
* mechanisms and business logic.
1624
*
1725
* @ingroup AsyncTCPClient
1826
*/
@@ -81,9 +89,10 @@ namespace async_tcp {
8189
async_work_on_timeout *worker) { // NOLINT
8290
(void)context;
8391
if (worker && worker->user_data) {
84-
const auto pBridge = static_cast<EventBridge *>(worker->user_data);
85-
pBridge->doWork();
86-
pBridge->releaseOwnership();
92+
const auto local_bridge =
93+
static_cast<EventBridge *>(worker->user_data)
94+
->releaseOwnership();
95+
local_bridge->doWork();
8796
} else {
8897
DEBUGV("\033[1;31m[AC-%d][%llu][ERROR] "
8998
"EventBridge::ephemeral_bridging_function - invalid worker "

src/TcpClient.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ namespace async_tcp {
196196
assert(m_writer && "TcpWriter must be configured for async operations");
197197

198198
// Atomically check if no write is in progress and set it to true if so
199-
bool expected = false;
200-
if (!m_writer->tryStartWrite(expected)) {
199+
if (bool expected = false; !m_writer->tryStartWrite(expected)) {
201200
DEBUGWIRE("[TcpClient] Write operation already in progress, rejecting new write\n");
202201
return PICO_ERROR_RESOURCE_IN_USE;
203202
}

src/TcpWriteHandler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
*/
1313

1414
#include "TcpWriteHandler.hpp"
15-
#include "lwip/tcp.h"
1615

1716
namespace async_tcp {
1817

@@ -25,7 +24,7 @@ namespace async_tcp {
2524

2625
void TcpWriteHandler::onWork() {
2726
if (!m_data || m_size == 0) {
28-
// No valid data to write - let the cleanup mechanism handle destruction
27+
// No valid data to write - let the cleanup mechanism handle destruction.
2928
return;
3029
}
3130

0 commit comments

Comments
 (0)