Skip to content

Commit 2360788

Browse files
committed
Improve mqueue memory safety
This commit fixes potential crash in mo_mq_items by adding NULL pointer validation. In addition, it adds unlikely() branch prediction hints for error conditions.
1 parent 648653a commit 2360788

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

include/sys/mqueue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,8 @@ message_t *mo_mq_peek(mq_t *mq);
2222

2323
static inline int32_t mo_mq_items(mq_t *mq)
2424
{
25+
/* Add NULL safety to prevent crashes */
26+
if (unlikely(!mq || !mq->q))
27+
return 0;
2528
return queue_count(mq->q);
2629
}

kernel/mqueue.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77
#include <sys/task.h>
88

99
#include "private/error.h"
10+
#include "private/utils.h"
1011

1112
mq_t *mo_mq_create(uint16_t max_items)
1213
{
1314
mq_t *mq = malloc(sizeof *mq);
14-
if (!mq)
15+
if (unlikely(!mq))
1516
return NULL;
1617

1718
mq->q = queue_create(max_items);
18-
if (!mq->q) {
19+
if (unlikely(!mq->q)) {
1920
free(mq);
2021
return NULL;
2122
}
@@ -24,22 +25,33 @@ mq_t *mo_mq_create(uint16_t max_items)
2425

2526
int32_t mo_mq_destroy(mq_t *mq)
2627
{
28+
if (unlikely(!mq))
29+
return ERR_OK; /* Destroying NULL is no-op */
30+
31+
if (unlikely(!mq->q))
32+
return ERR_FAIL; /* Invalid mqueue state */
33+
2734
CRITICAL_ENTER();
2835

29-
if (queue_count(mq->q) != 0) { /* refuse to destroy non-empty q */
36+
if (unlikely(queue_count(mq->q) != 0)) { /* refuse to destroy non-empty q */
3037
CRITICAL_LEAVE();
3138
return ERR_MQ_NOTEMPTY;
3239
}
3340

41+
/* Safe to destroy now - no need to hold critical section */
42+
CRITICAL_LEAVE();
43+
3444
queue_destroy(mq->q);
3545
free(mq);
3646

37-
CRITICAL_LEAVE();
3847
return ERR_OK;
3948
}
4049

4150
int32_t mo_mq_enqueue(mq_t *mq, message_t *msg)
4251
{
52+
if (unlikely(!mq || !mq->q || !msg))
53+
return ERR_FAIL;
54+
4355
int32_t rc;
4456

4557
CRITICAL_ENTER();
@@ -52,6 +64,9 @@ int32_t mo_mq_enqueue(mq_t *mq, message_t *msg)
5264
/* remove oldest message (FIFO) */
5365
message_t *mo_mq_dequeue(mq_t *mq)
5466
{
67+
if (unlikely(!mq || !mq->q))
68+
return NULL;
69+
5570
message_t *msg;
5671

5772
CRITICAL_ENTER();
@@ -64,6 +79,9 @@ message_t *mo_mq_dequeue(mq_t *mq)
6479
/* inspect head without removing */
6580
message_t *mo_mq_peek(mq_t *mq)
6681
{
82+
if (unlikely(!mq || !mq->q))
83+
return NULL;
84+
6785
message_t *msg;
6886

6987
CRITICAL_ENTER();

0 commit comments

Comments
 (0)