Skip to content

Commit

Permalink
net: lwm2m: Make LwM2M message allocation thread safe
Browse files Browse the repository at this point in the history
The LwM2M message allocation was not thread safe, i. e. the message was
acquired by setting the ctx pointer, and it was freed by clearing the
entire message structure.

If preemptive threads were enabled, and memset() clearing the message
content was preempted, the message structure being currently zeroed
migh've been allocated and initialized by some other thread. If the
thread releasing the message resumed work, it would continue clearing
the freshly allocated and initialized message structure.

In order to prevent this, introduce a new global mutex, purely for
message allocation/release. This will prevent reallocating the message
during the release process. Since the mutex use is very simple, there's
no risk of a deadlock.

Signed-off-by: Robert Lubos <[email protected]>
  • Loading branch information
rlubos committed Oct 15, 2024
1 parent 6300e1b commit c892e00
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions subsys/net/lib/lwm2m/lwm2m_message_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
/* Resources */

/* Shared set of in-flight LwM2M messages */
static K_MUTEX_DEFINE(msg_lock);
static struct lwm2m_message messages[CONFIG_LWM2M_ENGINE_MAX_MESSAGES];
static struct lwm2m_block_context block1_contexts[NUM_BLOCK1_CONTEXT];
static struct lwm2m_message *ongoing_block2_tx;
Expand Down Expand Up @@ -517,18 +518,25 @@ struct lwm2m_message *find_msg(struct coap_pending *pending, struct coap_reply *
return NULL;
}


struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx)
{
struct lwm2m_message *msg = NULL;
size_t i;

k_mutex_lock(&msg_lock, K_FOREVER);

for (i = 0; i < CONFIG_LWM2M_ENGINE_MAX_MESSAGES; i++) {
if (!messages[i].ctx) {
messages[i].ctx = client_ctx;
return &messages[i];
msg = &messages[i];
break;
}
}

return NULL;
k_mutex_unlock(&msg_lock);

return msg;
}

void lm2m_message_clear_allocations(struct lwm2m_message *msg)
Expand Down Expand Up @@ -561,11 +569,13 @@ void lwm2m_reset_message(struct lwm2m_message *msg, bool release)
}

if (release) {
k_mutex_lock(&msg_lock, K_FOREVER);
#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)
release_output_block_ctx(&msg->out.block_ctx);
release_body_encode_buffer(&msg->body_encode_buffer.data);
#endif
(void)memset(msg, 0, sizeof(*msg));
k_mutex_unlock(&msg_lock);
} else {
msg->message_timeout_cb = NULL;
(void)memset(&msg->cpkt, 0, sizeof(msg->cpkt));
Expand Down

0 comments on commit c892e00

Please sign in to comment.