Skip to content

Commit 1443c34

Browse files
committed
Assert on event use after free
1 parent cacfd83 commit 1443c34

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

Doxyfile.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ EXCLUDE_SYMBOLS = AM_ASSERT_STATIC \
3838
AM_EVENT_TICK_DOMAIN_MASK \
3939
AM_EVENT_POOL_INDEX_BITS \
4040
AM_EVENT_POOL_INDEX_MASK \
41+
AM_EVENT_ID_LSW_BITS \
42+
AM_EVENT_ID_LSW_MASK \
4143
am_alignof_slist \
4244
am_alignof_slist_item \
4345
AM_ALIGNOF_SLIST \

libs/event/event.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct am_event *am_event_allocate_x(int id, int size, int margin) {
119119

120120
memset(event, 0, sizeof(*event));
121121
event->id = id;
122+
event->id_lsw = (uint32_t)id & AM_EVENT_ID_LSW_MASK;
122123
event->pool_index_plus_one =
123124
(unsigned)(i + 1) & AM_EVENT_POOL_INDEX_MASK;
124125

@@ -142,6 +143,12 @@ static void am_event_free_unsafe(const struct am_event **event) {
142143

143144
struct am_event *e = AM_CAST(struct am_event *, *event);
144145
AM_ASSERT(e->pool_index_plus_one <= AM_EVENT_POOLS_NUM_MAX);
146+
/*
147+
* Check if event is valid.
148+
* If the below assert hits, then the reason is likely
149+
* a use after free condition.
150+
*/
151+
AM_ASSERT(((uint32_t)e->id & AM_EVENT_ID_LSW_MASK) == e->id_lsw);
145152

146153
if (e->ref_counter > 1) {
147154
--e->ref_counter;
@@ -203,6 +210,16 @@ struct am_event *am_event_dup_x(
203210
const struct am_event_state *me = &am_event_state_;
204211
AM_ASSERT(me->npools > 0);
205212
AM_ASSERT(event->id >= AM_EVT_USER);
213+
if (!am_event_is_static(event)) {
214+
/*
215+
* Check if event is valid.
216+
* If the below assert hits, then the reason is likely
217+
* a use after free condition.
218+
*/
219+
AM_ASSERT(
220+
((uint32_t)event->id & AM_EVENT_ID_LSW_MASK) == event->id_lsw
221+
);
222+
}
206223
AM_ASSERT(margin >= 0);
207224

208225
struct am_event *dup = am_event_allocate_x(event->id, size, margin);
@@ -283,6 +300,12 @@ void am_event_inc_ref_cnt(const struct am_event *event) {
283300
}
284301

285302
AM_ASSERT(event->ref_counter < AM_EVENT_REF_COUNTER_MASK);
303+
/*
304+
* Check if event is valid.
305+
* If the below assert hits, then the reason is likely
306+
* a use after free condition.
307+
*/
308+
AM_ASSERT(((uint32_t)event->id & AM_EVENT_ID_LSW_MASK) == event->id_lsw);
286309

287310
struct am_event *e = AM_CAST(struct am_event *, event);
288311
struct am_event_state *me = &am_event_state_;
@@ -331,6 +354,16 @@ static enum am_event_rc am_event_push_x(
331354
const int capacity = am_queue_get_capacity(queue);
332355
AM_ASSERT(margin < capacity);
333356
AM_ASSERT(push);
357+
if (!am_event_is_static(event)) {
358+
/*
359+
* Check if event is valid.
360+
* If the below assert hits, then the reason is likely
361+
* a use after free condition.
362+
*/
363+
AM_ASSERT(
364+
((uint32_t)event->id & AM_EVENT_ID_LSW_MASK) == event->id_lsw
365+
);
366+
}
334367

335368
struct am_event *e = AM_CAST(struct am_event *, event);
336369
struct am_event_state *me = &am_event_state_;

libs/event/event.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define AM_EVENT_H_INCLUDED
3535

3636
#include <stdbool.h>
37+
#include <stdint.h>
3738

3839
#include "common/compiler.h"
3940
#include "queue/queue.h"
@@ -83,6 +84,9 @@
8384
#define AM_EVENT_POOL_INDEX_BITS 5
8485
#define AM_EVENT_POOL_INDEX_MASK ((1U << AM_EVENT_POOL_INDEX_BITS) - 1U)
8586

87+
#define AM_EVENT_ID_LSW_BITS 16
88+
#define AM_EVENT_ID_LSW_MASK ((1U << AM_EVENT_ID_LSW_BITS) - 1U)
89+
8690
extern const int am_alignof_event;
8791
extern const int am_alignof_event_ptr;
8892

@@ -105,19 +109,24 @@ enum am_event_rc {
105109
/** Event descriptor. */
106110
struct am_event {
107111
/** event ID */
108-
int id;
112+
int32_t id;
109113

110114
/** reference counter */
111-
unsigned ref_counter : AM_EVENT_REF_COUNTER_BITS;
115+
uint32_t ref_counter : AM_EVENT_REF_COUNTER_BITS;
112116
/** if set to zero, then event is statically allocated */
113-
unsigned pool_index_plus_one : AM_EVENT_POOL_INDEX_BITS;
117+
uint32_t pool_index_plus_one : AM_EVENT_POOL_INDEX_BITS;
114118
/** tick domain for time events */
115-
unsigned tick_domain : AM_EVENT_TICK_DOMAIN_BITS;
119+
uint32_t tick_domain : AM_EVENT_TICK_DOMAIN_BITS;
116120
/** PUB/SUB time event */
117-
unsigned pubsub_time : 1;
121+
uint32_t pubsub_time : 1;
122+
/**
123+
* Least significant word of id for allocated events.
124+
* Used for sanity checks.
125+
*/
126+
uint32_t id_lsw : AM_EVENT_ID_LSW_BITS;
118127
};
119128

120-
AM_ASSERT_STATIC(sizeof(struct am_event) == (2 * sizeof(int)));
129+
AM_ASSERT_STATIC(sizeof(struct am_event) == (2 * sizeof(int32_t)));
121130

122131
/** Event library state configuration. */
123132
struct am_event_state_cfg {

0 commit comments

Comments
 (0)