Package: minidlna
Version: 1.3.3+dfsg-1.1+b1
Severity: important
From: [email protected] <mailto:[email protected]> 

Dear Maintainer,

MiniDLNA crashes with a segmentation fault (SIGSEGV) during media file 
playback. The crash is reproducible and occurs while serving media files to 
DLNA clients. It manifests as a complete server crash, interrupting active 
playback sessions.

-- Symptoms --

The minidlnad process crashes with signal 11 (SIGSEGV) while serving a media 
file via HTTP. The crash appears during or after sending a response to a client 
HEAD or GET request for a media item. The systemd journal shows a core dump:

Signal: 11 (SEGV)
Process: minidlnad

-- Stack trace (obtained by compiling with debug symbols using 
DEB_BUILD_OPTIONS="nostrip noopt") --

#0 select_del (ev=0x..., flags=1) at ./select.c:135
ev0 = 0x184 <- corrupted pointer (not a valid address)
#1 CloseSocket_upnphttp (h=0x...) at ./upnphttp.c:126
#2 SendResp_dlnafile (h=0x..., object="7536.mkv") at ./upnphttp.c:2121
#3 ProcessHttpQuery_upnphttp (h=0x...) at ./upnphttp.c:1015
#4 Process_upnphttp (ev=0x...) at ./upnphttp.c:1145
#5 select_process (tv=0x...) at ./select.c:177
#6 main (argc=7, argv=0x...) at ./minidlna.c:1315

-- Root cause --

There are two related bugs:

Bug 1: CloseSocket_upnphttp() in upnphttp.c has no guard against being called
on an already-closed socket (h->ev.fd < 0). It can be called multiple times on
the same struct upnphttp from different code paths. Note that Delete_upnphttp()
-- which wraps CloseSocket_upnphttp() -- already correctly checks h->ev.fd >= 0
before calling it, but the guard is missing inside CloseSocket_upnphttp() 
itself.

Bug 2: select_del() in select.c has no guard against being called on an
already-deleted event (ev->index < 0). When CloseSocket_upnphttp() is called on
an already-closed socket, ev->index is -1 (set during the first deletion). The
condition (-1 < --nevents) evaluates to true, causing:
- events[-1] = ev0 -- writes before the events array (memory corruption)
- ev0->index = -1 -- corrupts a valid active event's index
Over subsequent connections this leads to events[nevents] containing a garbage
value (observed: 0x184) which is then dereferenced, causing the SIGSEGV.

-- Fix --

upnphttp.c -- add guard at the start of CloseSocket_upnphttp():

void
CloseSocket_upnphttp(struct upnphttp * h)
{
if(h->ev.fd < 0) /* already closed, avoid double-delete */
return;
event_module.del(&h->ev, EV_FLAG_CLOSING);
if(close(h->ev.fd) < 0)
{
DPRINTF(E_ERROR, L_HTTP, "CloseSocket_upnphttp: close(%d): %s\n", h->ev.fd, 
strerror(errno));
}
h->ev.fd = -1;
h->state = 100;
}

select.c -- add guard at the start of select_del(), before the existing 
assert():

static int
select_del(struct event *ev, int flags)
{
if(ev->index < 0) /* already deleted, avoid double-delete */
return (0);

assert(ev->fd < FD_SETSIZE);
...
}

The guard in select_del must be placed BEFORE the assert(ev->fd < FD_SETSIZE)
to prevent the assert from firing on an invalid fd value.

-- Verification --

After applying both fixes and recompiling with debug symbols, the crash no 
longer
occurs during playback. The fix has been tested on Debian Trixie 13.5 amd64 with
minidlna 1.3.3+dfsg-1.1, serving MKV files to a Samsung Series CDE DLNA client.

-- Note --

This bug is present in all current Debian builds of minidlna:
stable: 1.3.3+dfsg-1.1+b1
testing: 1.3.3+dfsg-1.1+b2
unstable: 1.3.3+dfsg-1.1+b2

These are binary-only rebuilds of the same unfixed source. The fix should also
be reported upstream to the ReadyMedia/MiniDLNA project at:
https://sourceforge.net/p/minidlna/bugs/

-- System information --

Debian GNU/Linux 13 (Trixie) 13.5, amd64
minidlna 1.3.3+dfsg-1.1+b1
Linux brix2

Regards,
Tamas Kohegyi

Reply via email to