Package: libmms0
Version: 0.6.4-3+b2
Severity: important
X-Debbugs-Cc: [email protected]

I'm reporting three bugs in libmms 0.6.4. All of them are in
interp_asf_header() in src/mms-common-funcs.h, and the input is the ASF
header the MMS server sends during the handshake, so it is fully
attacker-controlled and is parsed on every mms:// or mmsh:// connect
(mms.c:928, mmsh.c:435 and 737).

The parser walks the top-level ASF objects and advances i by each
object's 64-bit length field (i += length, line 282). Three problems:

1. An object with length 0 never advances the loop, and there is no
   timeout on this path: mms_connect() spins at 100% CPU forever. A
   60-byte header triggers it.
2. Same in the inner Header-Extension walk (j += l, line 270). A
   204-byte header.
3. The Stream-Bitrate-Properties case uses the 16-bit stream count
   directly as the loop bound (line 180) with no check against the
   object size or the header size. With 0xFFFF it reads up to about
   393 KB past the end of the object; the mms_t allocation is about
   136 KB total. ASan reports a heap-buffer-overflow READ at
   mms-common-funcs.h:182.

Any program linking libmms (mpd, audacious, xmms2, kget) can be hung
or crashed by a single connect to a malicious mms:// URL, a shared
link, or one entry in a playlist a daemon loads. Doesn't require 
authentication, one
request.

I tested it end to end on trixie with a small Python script that
speaks the MMS command protocol over TCP and serves a crafted ASF
header. A valid header connects normally; the 60-byte header hangs the
client at 100% CPU; the 58-byte OOB header reliably triggers the
out-of-bounds read, and the distro mpd 0.24.4 (libmms.so.0.0.2) segfaults
when the malicious URL is played (mpc add … && mpc play), the kernel
log shows the fault inside libmms.so.0.0.2. With the hang payload, mpd
stays up but its mms input thread spins at 100% CPU.

I have a minimal fix that I verified (valid headers still parse, all
three PoCs fail cleanly):
- outer walk: replace "if ((i + length) > this->asf_header_len) return;"
  with "if (length < 24 || length > (uint64_t)this->asf_header_len) return;"
- inner walk: add "if (l < 24) break;" after the existing (j + l) > length check
- bitrate loop: "for (j = 0; j < streams && (i + 32 + j * 6) <= 
this->asf_header_len; j++)"

Upstream has had no release since 2014, so I assume this will need to
go in as a Debian patch. I can send the .patch, a PoC generator and
the repro script.

Given the severity (unauthenticated, deterministic DoS / OOB heap
read), I'd also like to ask whether a CVE could be requested for this.

Thanks,
Adrian Pfeffer

-- System Information:
Debian Release: 13.7
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.12.107+deb13-amd64 (SMP w/18 CPU threads; PREEMPT)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libmms0 depends on:
ii  libc6  2.41-12+deb13u4

libmms0 recommends no packages.

libmms0 suggests no packages.

-- no debconf information

Reply via email to