From 194aba1da69632a021c7ac52ab4bf807233086b7 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Tue, 21 Jul 2026 16:19:54 +0200 Subject: [PATCH] MT#55283 media_socket: lock sink earlier when kernelizing To not come across the sink's mutation (e.g. `endpoint.address.family`) just lock way earlier, before to start processing and translating endpoint to the kernel related structs. Otherwise the other signaling path may mutate something which will make the sink unactual and provide to the `__re_address_translate_ep()` NULLed or garbage structs. Change-Id: I88d87ae88abe4e37aaa5d3cdda76ed0ca82e4842 (cherry picked from commit e16a2309e0c72809930d848f2f2d265beb4dde60) (cherry picked from commit dae81c11df213b904c8b5e01786adf38e8283315) --- daemon/media_socket.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 354060c7f..86964d1ba 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1782,8 +1782,17 @@ static const char *kernelize_one(kernelize_state *s, if (MEDIA_ISSET(sink_media, BLOCK_EGRESS)) return NULL; - if (!sink->endpoint.address.family) + /* XXX nested lock, avoid possible deadlock. should be reworked not to + * require a nested lock */ + if (sink != stream && mutex_trylock(&sink->lock)) { + return ""; // indicate deadlock + } + + if (!sink->endpoint.address.family) { + if (sink != stream) + mutex_unlock(&sink->lock); return NULL; + } if (sink->selected_sfd) ilog(LOG_INFO, "Kernelizing media stream: %s%s%s -> %s | %s -> %s%s%s", @@ -1798,16 +1807,25 @@ static const char *kernelize_one(kernelize_state *s, const struct streamhandler *handler = determine_sink_handler(stream, sink_handler); - if (!handler->out->kernel) + if (!handler->out->kernel) { + if (sink != stream) + mutex_unlock(&sink->lock); return "protocol not supported by kernel module"; + } __auto_type reti = &s->reti.target; // any output at all? - if (s->non_forwarding || !sink->selected_sfd || !sink->selected_sfd->socket.family) + if (s->non_forwarding || !sink->selected_sfd || !sink->selected_sfd->socket.family) { + if (sink != stream) + mutex_unlock(&sink->lock); return NULL; // no output - if (!PS_ISSET(sink, FILLED)) + } + if (!PS_ISSET(sink, FILLED)) { + if (sink != stream) + mutex_unlock(&sink->lock); return NULL; + } // fill output struct __auto_type credi = g_new0(struct rtpengine_command_destination, 1); @@ -1848,13 +1866,6 @@ static const char *kernelize_one(kernelize_state *s, if (MEDIA_ISSET(media, ECHO) || sink_handler->attrs.transcoding) redi->output.ssrc_subst = 1; - // XXX nested lock, avoid possible deadlock. should be reworked not to - // require a nested lock - if (sink != stream && mutex_trylock(&sink->lock)) { - g_free(credi); - return ""; // indicate deadlock - } - __re_address_translate_ep(&redi->output.dst_addr, &sink->endpoint); __re_address_translate_ep(&redi->output.src_addr, &sink->selected_sfd->socket.local); redi->output.iface_stats = sink->selected_sfd->local_intf->stats;