You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
7.3 KiB
294 lines
7.3 KiB
This patch fixes security holes caused by potential buffer overflows |
|
in the implementation of the gzprintf() function in zlib 1.1.4. The |
|
security holes are fixed for platforms providing vsnprintf(3) and |
|
snprintf(3) only. This patch is derived from a prepared security patch, |
|
originally created by Kelledin <kelledin@users.sourceforge.net>. The |
|
OpenPKG project reduced the patch in size and fixed the configuration |
|
checks. |
|
|
|
diff -ru3 zlib-1.1.4.orig/configure zlib-1.1.4/configure |
|
--- zlib-1.1.4.orig/configure Wed Jul 8 20:19:35 1998 |
|
+++ zlib-1.1.4/configure Thu Feb 27 15:14:54 2003 |
|
@@ -155,7 +155,212 @@ |
|
echo "Checking for unistd.h... No." |
|
fi |
|
|
|
-cat > $test.c <<EOF |
|
+cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+ |
|
+#if (defined(__MSDOS__) || defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)) && !defined(STDC) |
|
+# define STDC |
|
+#endif |
|
+ |
|
+int main() |
|
+{ |
|
+#ifndef STDC |
|
+ choke me |
|
+#endif |
|
+ |
|
+ return 0; |
|
+} |
|
+EOF |
|
+ |
|
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ echo "Checking whether to use vsnprintf() or snprintf()... using vsnprintf()" |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest(char *fmt, ...) |
|
+{ |
|
+ char buf[20]; |
|
+ va_list ap; |
|
+ |
|
+ va_start(ap, fmt); |
|
+ vsnprintf(buf, sizeof(buf), fmt, ap); |
|
+ va_end(ap); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest("Hello%d\n", 1)); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_vsnprintf" |
|
+ echo "Checking for vsnprintf() in stdio.h... Yes." |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest(char *fmt, ...) |
|
+{ |
|
+ int i; |
|
+ char buf[20]; |
|
+ va_list ap; |
|
+ |
|
+ va_start(ap, fmt); |
|
+ i = vsnprintf(buf, sizeof(buf), fmt, ap); |
|
+ va_end(ap); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest("Hello%d\n", 1)); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_vsnprintf_return" |
|
+ echo "Checking for return value of vsnprintf()... Yes." |
|
+ else |
|
+ echo "Checking for return value of vsnprintf()... No." |
|
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib" |
|
+ echo " can build but will be open to possible string-format security" |
|
+ echo " vulnerabilities." |
|
+ fi |
|
+ else |
|
+ echo "Checking for vsnprintf() in stdio.h... No." |
|
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" |
|
+ echo " can build but will be open to possible buffer-overflow security" |
|
+ echo " vulnerabilities." |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest(char *fmt, ...) |
|
+{ |
|
+ int i; |
|
+ char buf[20]; |
|
+ va_list ap; |
|
+ |
|
+ va_start(ap, fmt); |
|
+ i = vsprintf(buf, fmt, ap); |
|
+ va_end(ap); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest("Hello%d\n", 1)); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_vsprintf_return" |
|
+ echo "Checking for return value of vsprintf()... Yes." |
|
+ else |
|
+ echo "Checking for return value of vsprintf()... No." |
|
+ echo " WARNING: apparently vsprintf() does not return a value. zlib" |
|
+ echo " can build but will be open to possible string-format security" |
|
+ echo " vulnerabilities." |
|
+ fi |
|
+ fi |
|
+else |
|
+ echo "Checking whether to use vsnprintf() or snprintf()... using snprintf()" |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest() |
|
+{ |
|
+ char buf[20]; |
|
+ |
|
+ snprintf(buf, sizeof(buf), "%s", "foo"); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest()); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_snprintf" |
|
+ echo "Checking for snprintf() in stdio.h... Yes." |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest(char *fmt, ...) |
|
+{ |
|
+ int i; |
|
+ char buf[20]; |
|
+ |
|
+ i = snprintf(buf, sizeof(buf), "%s", "foo"); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest()); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_snprintf_return" |
|
+ echo "Checking for return value of snprintf()... Yes." |
|
+ else |
|
+ echo "Checking for return value of snprintf()... No." |
|
+ echo " WARNING: apparently snprintf() does not return a value. zlib" |
|
+ echo " can build but will be open to possible string-format security" |
|
+ echo " vulnerabilities." |
|
+ fi |
|
+ else |
|
+ echo "Checking for snprintf() in stdio.h... No." |
|
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" |
|
+ echo " can build but will be open to possible buffer-overflow security" |
|
+ echo " vulnerabilities." |
|
+ |
|
+ cat >$test.c <<EOF |
|
+#include <stdio.h> |
|
+#include <stdarg.h> |
|
+ |
|
+int mytest(char *fmt, ...) |
|
+{ |
|
+ int i; |
|
+ char buf[20]; |
|
+ |
|
+ i = sprintf(buf, "%s", "foo"); |
|
+ return 0; |
|
+} |
|
+ |
|
+int main() |
|
+{ |
|
+ return (mytest()); |
|
+} |
|
+EOF |
|
+ |
|
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
|
+ CFLAGS="$CFLAGS -DHAS_sprintf_return" |
|
+ echo "Checking for return value of sprintf()... Yes." |
|
+ else |
|
+ echo "Checking for return value of sprintf()... No." |
|
+ echo " WARNING: apparently sprintf() does not return a value. zlib" |
|
+ echo " can build but will be open to possible string-format security" |
|
+ echo " vulnerabilities." |
|
+ fi |
|
+ fi |
|
+fi |
|
+ |
|
+cat >$test.c <<EOF |
|
#include <errno.h> |
|
int main() { return 0; } |
|
EOF |
|
diff -ru3 zlib-1.1.4.orig/gzio.c zlib-1.1.4/gzio.c |
|
--- zlib-1.1.4.orig/gzio.c Mon Mar 11 14:16:01 2002 |
|
+++ zlib-1.1.4/gzio.c Thu Feb 27 14:29:26 2003 |
|
@@ -530,13 +530,31 @@ |
|
|
|
va_start(va, format); |
|
#ifdef HAS_vsnprintf |
|
+# ifdef HAS_vsnprintf_return |
|
+ len = vsnprintf(buf, sizeof(buf), format, va); |
|
+ va_end(va); |
|
+ if (len <= 0 || len >= sizeof(buf)) |
|
+ return 0; |
|
+# else |
|
(void)vsnprintf(buf, sizeof(buf), format, va); |
|
+ va_end(va); |
|
+ len = strlen(buf); |
|
+ if (len <= 0) |
|
+ return 0; |
|
+# endif |
|
#else |
|
+# ifdef HAS_vsprintf_return |
|
+ len = vsprintf(buf, format, va); |
|
+ va_end(va); |
|
+ if (len <= 0 || len >= sizeof(buf)) |
|
+ return 0; |
|
+# else |
|
(void)vsprintf(buf, format, va); |
|
-#endif |
|
va_end(va); |
|
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ |
|
if (len <= 0) return 0; |
|
+# endif |
|
+#endif |
|
|
|
return gzwrite(file, buf, (unsigned)len); |
|
} |
|
@@ -553,14 +571,31 @@ |
|
int len; |
|
|
|
#ifdef HAS_snprintf |
|
+# ifdef HAS_snprintf_return |
|
+ len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, |
|
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
|
+ if (len <= 0 || len >= sizeof(buf)) |
|
+ return 0; |
|
+# else |
|
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, |
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
|
+ len = strlen(buf); |
|
+ if (len <= 0) |
|
+ return 0; |
|
+# endif |
|
#else |
|
+# ifdef HAS_sprintf_return |
|
+ len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, |
|
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
|
+ if (len <= 0 || len >= sizeof(buf)) |
|
+ return 0; |
|
+# else |
|
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, |
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
|
-#endif |
|
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ |
|
if (len <= 0) return 0; |
|
+# endif |
|
+#endif |
|
|
|
return gzwrite(file, buf, len); |
|
}
|
|
|