owntone / owntone-server

Linux/FreeBSD DAAP (iTunes) and MPD audio server with support for AirPlay 1 and 2 speakers (multiroom), Apple Remote (and compatibles), Chromecast, Spotify and internet radio.
https://owntone.github.io/owntone-server
GNU General Public License v2.0
2.1k stars 237 forks source link

Segfault when a client does not provide User Agent string #571

Closed rokm closed 6 years ago

rokm commented 6 years ago

I have set up a forked-daapd on a Raspberry Pi with a library containing ~15k tracks. When I try to connect to the server using Exaile and its DAAP client plugin, the server crashes with segmentation fault.

This happens both with the packaged version (24.2) and git master - with the latter, the following backtrace is obtained:

Thread 12 "httpd" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x69fff1a0 (LWP 4133)]
strlen () at ../sysdeps/arm/armv6/strlen.S:26
26  ../sysdeps/arm/armv6/strlen.S: No such file or directory.
(gdb) bt
#0  strlen () at ../sysdeps/arm/armv6/strlen.S:26
#1  0x74f1f928 in __GI___strdup (s=0x0) at strdup.c:41
#2  0x00028594 in cache_daap_add (
    query=0x69602310 "/databases/1/items?session-id=2086164548&meta=dmap.itemid,dmap.itemname,daap.songalbum,daap.songartist,daap.songformat,daap.songtime,daap.songsize,daap.songgenre,daap.songyear,daap.songtracknumber", ua=0x0,
    is_remote=0, msec=msec@entry=2064) at cache.c:1368
#3  0x000394c8 in daap_request (req=req@entry=0x6960b7a8,
    uri_parsed=uri_parsed@entry=0x69610300) at httpd_daap.c:2315
#4  0x000342d8 in httpd_gen_cb (req=0x6960b7a8, arg=<optimized out>)
    at httpd.c:837
#5  0x754cc70c in ?? () from /usr/lib/arm-linux-gnueabihf/libevent-2.0.so.5
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

So the problem is that in cache.c:1368, strdup() is called with a NULL ua parameter, because the client did not supply the User Agent string.

The issue does not occur with a smaller test music library (on Pi), nor when the whole library is served from a x86_64 Debian VM - presumably because in both cases, the query's execution time did not exceed the threshold and not caching was attempted...

ejurgensen commented 6 years ago

Good catch, and excellent issue report. Thanks a lot!