Skip to content

Commit 03ca20d

Browse files
spencercwgnif
authored andcommitted
[client] overlay/msg: fix race condition in render
If an overlay is closed with overlayMsg_close, the message can be freed while it is still being used by msg_render, resulting in a segfault. Lock the message list for the duration of msg_render to fix this.
1 parent 7e9e38f commit 03ca20d

File tree

3 files changed

+37
-23
lines changed

3 files changed

+37
-23
lines changed

client/src/overlay/msg.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,14 @@ static bool msg_needsOverlay(void * udata)
8585
static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
8686
int maxRects)
8787
{
88+
ll_lock(l_msg.messages);
89+
8890
struct Msg * msg;
89-
if (!ll_peek_head(l_msg.messages, (void **)&msg))
91+
if (!ll_peek_head_nl(l_msg.messages, (void **)&msg))
92+
{
93+
ll_unlock(l_msg.messages);
9094
return 0;
95+
}
9196

9297
ImVec2 * screen = overlayGetScreenSize();
9398
igSetNextWindowBgAlpha(0.8f);
@@ -163,14 +168,15 @@ static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
163168

164169
if (destroy)
165170
{
166-
(void)ll_shift(l_msg.messages, NULL);
171+
(void)ll_shift_nl(l_msg.messages, NULL);
167172
freeMsg(msg);
168173
app_invalidateOverlay(false);
169174
}
170175

171176
overlayGetImGuiRect(windowRects);
172177
igEnd();
173178

179+
ll_unlock(l_msg.messages);
174180
return 1;
175181
}
176182

common/include/common/ll.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ struct ll
4141
};
4242

4343
struct ll * ll_new(void);
44-
void ll_free (struct ll * list);
45-
void ll_push (struct ll * list, void * data);
46-
bool ll_shift (struct ll * list, void ** data);
47-
bool ll_peek_head(struct ll * list, void ** data);
48-
bool ll_peek_tail(struct ll * list, void ** data);
44+
void ll_free (struct ll * list);
45+
void ll_push (struct ll * list, void * data);
46+
bool ll_shift (struct ll * list, void ** data);
47+
bool ll_shift_nl (struct ll * list, void ** data);
48+
bool ll_peek_head (struct ll * list, void ** data);
49+
bool ll_peek_head_nl(struct ll * list, void ** data);
50+
bool ll_peek_tail (struct ll * list, void ** data);
51+
bool ll_peek_tail_nl(struct ll * list, void ** data);
4952

5053
#define ll_lock(ll) LG_LOCK((ll)->lock)
5154
#define ll_unlock(ll) LG_UNLOCK((ll)->lock)

common/src/ll.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,18 @@ void ll_push(struct ll * list, void * data)
8383
bool ll_shift(struct ll * list, void ** data)
8484
{
8585
LG_LOCK(list->lock);
86+
bool result = ll_shift_nl(list, data);
87+
LG_UNLOCK(list->lock);
88+
return result;
89+
}
90+
91+
bool ll_shift_nl(struct ll * list, void ** data)
92+
{
8693
if (!list->head)
87-
{
88-
LG_UNLOCK(list->lock);
8994
return false;
90-
}
9195

9296
struct ll_item * item = list->head;
9397
ll_removeNL(list, item);
94-
LG_UNLOCK(list->lock);
9598

9699
if (data)
97100
*data = item->data;
@@ -103,29 +106,31 @@ bool ll_shift(struct ll * list, void ** data)
103106
bool ll_peek_head(struct ll * list, void ** data)
104107
{
105108
LG_LOCK(list->lock);
109+
bool result = ll_peek_head_nl(list, data);
110+
LG_UNLOCK(list->lock);
111+
return result;
112+
}
113+
114+
bool ll_peek_head_nl(struct ll * list, void ** data)
115+
{
106116
if (!list->head)
107-
{
108-
LG_UNLOCK(list->lock);
109117
return false;
110-
}
111-
112118
*data = list->head->data;
113-
LG_UNLOCK(list->lock);
114-
115119
return true;
116120
}
117121

118122
bool ll_peek_tail(struct ll * list, void ** data)
119123
{
120124
LG_LOCK(list->lock);
125+
bool result = ll_peek_tail_nl(list, data);
126+
LG_UNLOCK(list->lock);
127+
return result;
128+
}
129+
130+
bool ll_peek_tail_nl(struct ll * list, void ** data)
131+
{
121132
if (!list->tail)
122-
{
123-
LG_UNLOCK(list->lock);
124133
return false;
125-
}
126-
127134
*data = list->tail->data;
128-
LG_UNLOCK(list->lock);
129-
130135
return true;
131136
}

0 commit comments

Comments
 (0)