Package: mpg123
Version: 0.59r-19
Severity: grave
Tags: security patch sarge pending
Justification: user security hole
[This problem is fixed already in 0.59r-20 (currently in unstable). I'm
filing this report so the issue can be tracked by the testing security team
more easily.]
The security patch to the http parser (httpget.c) applied in 0.59r-18
has introduced potential integer overflows in several places. They are
triggered when a playlist contains extremely long URL strings. As mpg123
allows to access playlists via http, this is a potential remote exploit.
I'm attaching the patch applied in 0.59r-20 to fix the integer overflow.
The only other change in 0.59r-20 with respect to the version in sarge
is a fix for a regression caused by the same security patch to 0.59r-18
(cf. #294801).
Daniel.
-- System Information:
Debian Release: 3.1
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.4.27
Locale: LANG=C, LC_CTYPE=de_DE (charmap=ISO-8859-1)
Versions of packages mpg123 depends on:
ii libc6 2.3.2.ds1-21 GNU C Library: Shared libraries an
-- no debconf information
---------------------
PatchSet 220
Date: 2005/05/08 18:38:50
Author: kobras
Branch: HEAD
Tag: (none)
Log:
Fix integer overflows in http parser. [dk]
Members:
httpget.c:1.14->1.15
debian/changelog:1.44->1.45
Index: debian/mpg123/httpget.c
diff -u debian/mpg123/httpget.c:1.14 debian/mpg123/httpget.c:1.15
--- debian/mpg123/httpget.c:1.14 Sun May 8 18:46:14 2005
+++ debian/mpg123/httpget.c Sun May 8 19:38:50 2005
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/types.h>
@@ -197,7 +198,7 @@
int http_open (char *url)
{
char *purl, *host, *request, *sptr;
- size_t linelength, linelengthbase;
+ size_t linelength, linelengthbase, tmp;
unsigned long myip;
unsigned int myport;
int sock;
@@ -227,6 +228,11 @@
/* The length of purl is upper bound by 3*strlen(url) + 1 if
* everything in it is a space */
+ if (strlen(url) >= ULONG_MAX/3) {
+ fprintf (stderr, "URL too long. Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
purl = (char *)malloc(strlen(url)*3 + 1);
if (!purl) {
fprintf (stderr, "malloc() failed, out of memory.\n");
@@ -272,11 +278,27 @@
linelengthbase = 62 + strlen(prgName) + strlen(prgVersion)
+ strlen(ACCEPT_HEAD);
- if(httpauth)
- linelengthbase += (strlen(httpauth) + 1) * 4;
+ if(httpauth) {
+ tmp = (strlen(httpauth) + 1) * 4;
+ if (strlen(httpauth) >= ULONG_MAX/4 - 1 ||
+ linelengthbase + tmp < linelengthbase) {
+ fprintf(stderr, "HTTP authentication too long.
Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
+ linelengthbase += tmp;
+ }
- if(httpauth1)
- linelengthbase += (strlen(httpauth1) + 1) * 4;
+ if(httpauth1) {
+ tmp = (strlen(httpauth1) + 1) * 4;
+ if (strlen(httpauth1) >= ULONG_MAX/4 - 1 ||
+ linelengthbase + tmp < linelengthbase) {
+ fprintf(stderr, "HTTP authentication too long.
Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
+ linelengthbase += tmp;
+ }
do {
if (proxyip != INADDR_NONE) {
@@ -284,9 +306,23 @@
myip = proxyip;
linelength = linelengthbase + strlen(purl);
- if(host)
+ if (linelength < linelengthbase) {
+ fprintf(stderr, "URL too long. Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
+
+ if(host) {
+ tmp = 9 + strlen(host) + 5;
+ if (strlen(host) >= ULONG_MAX - 14 ||
+ linelength + tmp < linelength) {
+ fprintf(stderr, "Hostname info too
long. Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
/* "Host: <host>:<port>\r\n" */
- linelength += 9 + strlen(host) + 5;
+ linelength += tmp;
+ }
/* Buffer is reused for receiving later on, so ensure
* minimum size. */
@@ -316,9 +352,23 @@
}
linelength = linelengthbase + strlen(sptr);
- if (host)
+ if (linelength < linelengthbase) {
+ fprintf(stderr, "URL too long. Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
+
+ if(host) {
+ tmp = 9 + strlen(host) + 5;
+ if (strlen(host) >= ULONG_MAX - 14 ||
+ linelength + tmp < linelength) {
+ fprintf(stderr, "Hostname info too
long. Skipping...\n");
+ sock = -1;
+ goto exit;
+ }
/* "Host: <host>:<port>\r\n" */
- linelength += 9 + strlen(host) + 5;
+ linelength += tmp;
+ }
/* Buffer is reused for receiving later on, so ensure
* minimum size. */
Index: debian/mpg123/debian/changelog
diff -u debian/mpg123/debian/changelog:1.44 debian/mpg123/debian/changelog:1.45
--- debian/mpg123/debian/changelog:1.44 Sun May 8 18:46:14 2005
+++ debian/mpg123/debian/changelog Sun May 8 19:38:50 2005
@@ -1,9 +1,11 @@
-mpg123 (0.59r-20) unstable; urgency=medium
+mpg123 (0.59r-20) unstable; urgency=high
+ * httpget.c: Fix integer overflows in http parser, introduced by
+ security patch for CAN-2004-0982.
* httpget.c: Ensure minimum size of receive buffer to fix regression
in 0.59r-18, caused by patch for CAN-2004-0982. Closes: #294801
- -- Daniel Kobras <[EMAIL PROTECTED]> Sun, 8 May 2005 18:43:18 +0200
+ -- Daniel Kobras <[EMAIL PROTECTED]> Sun, 8 May 2005 19:37:18 +0200
mpg123 (0.59r-19) unstable; urgency=high