1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-02-12 16:11:54 +00:00

Remove access to freed memory

If rtsp_unlink_waiting(m) is called and actually destroys m, it's not
safe to pass it to rtsp_unlink_outgoing later.

We make rtsp_unlink_waiting and rtsp_unlink_outgoing return true if they
destroy the message, and in this case we make sure not to try freeing it
again.
This commit is contained in:
Andrey Alekseenko 2020-02-21 22:12:53 -05:00 committed by Alberto Fanjul
parent 57d05a1808
commit be54804768

View file

@ -2716,7 +2716,7 @@ error:
return r; return r;
} }
static void rtsp_unlink_waiting(struct rtsp_message *m) static bool rtsp_unlink_waiting(struct rtsp_message *m)
{ {
if (m->is_waiting) { if (m->is_waiting) {
sd_event_source_unref(m->timer_source); sd_event_source_unref(m->timer_source);
@ -2725,7 +2725,9 @@ static void rtsp_unlink_waiting(struct rtsp_message *m)
m->is_waiting = false; m->is_waiting = false;
--m->bus->waiting_cnt; --m->bus->waiting_cnt;
rtsp_message_unref(m); rtsp_message_unref(m);
return true;
} }
return false;
} }
static void rtsp_link_outgoing(struct rtsp_message *m) static void rtsp_link_outgoing(struct rtsp_message *m)
@ -2736,7 +2738,7 @@ static void rtsp_link_outgoing(struct rtsp_message *m)
rtsp_message_ref(m); rtsp_message_ref(m);
} }
static void rtsp_unlink_outgoing(struct rtsp_message *m) static bool rtsp_unlink_outgoing(struct rtsp_message *m)
{ {
if (m->is_outgoing) { if (m->is_outgoing) {
shl_dlist_unlink(&m->list); shl_dlist_unlink(&m->list);
@ -2744,7 +2746,9 @@ static void rtsp_unlink_outgoing(struct rtsp_message *m)
m->is_sending = false; m->is_sending = false;
--m->bus->outgoing_cnt; --m->bus->outgoing_cnt;
rtsp_message_unref(m); rtsp_message_unref(m);
return true;
} }
return false;
} }
static int rtsp_incoming_message(struct rtsp_message *m) static int rtsp_incoming_message(struct rtsp_message *m)
@ -2822,10 +2826,11 @@ static int rtsp_write_message(struct rtsp_message *m)
if (m->sent >= m->raw_size) { if (m->sent >= m->raw_size) {
/* no need to wait for answer if no-body listens */ /* no need to wait for answer if no-body listens */
if (!m->cb_fn) if (!m->cb_fn)
rtsp_unlink_waiting(m); if (rtsp_unlink_waiting(m))
m = NULL;
/* might destroy the message */ /* might destroy the message */
rtsp_unlink_outgoing(m); if (m)
rtsp_unlink_outgoing(m);
} }
return 0; return 0;
@ -3245,10 +3250,12 @@ static void rtsp_drop_message(struct rtsp_message *m)
/* never interrupt messages while being partly sent */ /* never interrupt messages while being partly sent */
if (!m->is_sending) if (!m->is_sending)
rtsp_unlink_outgoing(m); if (rtsp_unlink_outgoing(m))
m = NULL;
/* remove from waiting list so neither timeouts nor completions fire */ /* remove from waiting list so neither timeouts nor completions fire */
rtsp_unlink_waiting(m); if (m)
rtsp_unlink_waiting(m);
} }
void rtsp_call_async_cancel(struct rtsp *bus, uint64_t cookie) void rtsp_call_async_cancel(struct rtsp *bus, uint64_t cookie)