From c892e00e3e5e2bf3d1900b47d890375f78377d9b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 11 Oct 2024 17:15:04 +0200 Subject: [PATCH] net: lwm2m: Make LwM2M message allocation thread safe 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 --- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index ac765aa0fc6716f..abc8a39ae8f3e75 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -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; @@ -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) @@ -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));