Skip to content

Commit

Permalink
nrf_rpc: fix possible data race at initialization
Browse files Browse the repository at this point in the history
Fix possible data race that may happen when the transport
receives the first nRF RPC packet before the thread that
initializes nRF RPC marks the group's trasport as initialized.

Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>
  • Loading branch information
Damian-Nordic authored and rlubos committed Nov 20, 2024
1 parent 96bb591 commit 58fe4d4
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions nrf_rpc/nrf_rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,19 +414,22 @@ static int transport_init(nrf_rpc_tr_receive_handler_t receive_cb)

NRF_RPC_ASSERT(transport != NULL);

err = transport->api->init(transport, receive_cb, NULL);
if (err) {
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
continue;
}

/* Initialize all dependencies of `receive_handler` before calling the transport
* init to avoid possible data race if `receive_handler` was invoked before this
* function was completed. */
if (auto_free_rx_buf(transport)) {
err = nrf_rpc_os_event_init(&data->decode_done_event);
if (err < 0) {
continue;
}
}

err = transport->api->init(transport, receive_cb, NULL);
if (err) {
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
continue;
}

group->data->transport_initialized = true;

if (group->flags & NRF_RPC_FLAGS_INITIATOR) {
Expand Down Expand Up @@ -694,7 +697,7 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
* either we are not an initiator, which is indicated by NRF_RPC_FLAGS_INITIATOR
* flag, or the remote has missed our init packet.
*/
send_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN) && group_data->transport_initialized;
send_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN);

/*
* Spawn the async task only if necessary. The async task is used to avoid sending the init
Expand Down Expand Up @@ -742,6 +745,12 @@ static void receive_handler(const struct nrf_rpc_tr *transport, const uint8_t *p
err = -NRF_EBADMSG;
goto cleanup_and_exit;
}

/* Mark the transport as initialized in case the first packet arrives sooner than
* `nrf_rpc_init` does that. Without this, an attempt to allocate a buffer for the
* response to this packet would fail.
*/
group->data->transport_initialized = true;
}

NRF_RPC_DBG("Received %d bytes packet from %d to %d, type 0x%02X, "
Expand Down

0 comments on commit 58fe4d4

Please sign in to comment.