6174147 2001-03-05 13:15 +0000  /62 rader/ pre <pre@GEEKGANG.CO.UK>
Sänt av: joel@lysator.liu.se
Importerad: 2001-03-05  21:30  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: pre@GEEKGANG.CO.UK
Mottagare: Bugtraq (import) <15738>
Ärende: [GSA2001-01] PHP IMAP overflow fix problems
------------------------------------------------------------
              geekgang Security Advisory [gsa2001-01]

                        [www.geekgang.co.uk]
                      © Copyright 2001 geekgang

ID:             geekgang GSA2001-01 01 v1.0
Topic:          PHP IMAP overflow fix problems
Status:         Released 5th March, 2001
Author:         pre

[Abstract]
PHP 4.0.4 contains a fix for a buffer overflow in the imap module.
Unfortunately this fix breaks the imap module under some circumstances
due to its interaction with the WU c-client library which PHP uses to
implement the imap protocol.

[Description]
The imap module in PHP contained a buffer overflow in versions prior
to 4.0.4, due to improper use of strcpy(). The fix in 4.0.4 resolves
the strcpy() problem, but causes the imap module to fail under some
circumstances. For example, the IMP WebMail system fails to work
correctly under 4.0.4, so PHP 4.0.3 is extensively deployed for use
with IMP.

A number of WebMail systems are likely to be vulnerable to this issue.

The PHP imap module relies on the WU c-client library to actually
perform imap (and POP3, NNTP and local mailbox) requests.
Additionally, the c-client library uses callbacks into PHP in order to
ascertain the username and password for the requested connection.

The patch in PHP 4.0.4 changed the behavior of the imap module such
that the username and password is no longer stored beyond the initial
imap_open() call. However, the c-client library may still call the
callback function to retrieve the username and password outside of
this call, which then returns garbage data. For example, the
imap_reopen() function triggers this call sequence.

This issue appears to be fixed in the current CVS version of PHP (I
haven't tested it, just looked at the code).

The gsa2001-01.diff patch against php-4.0.4pl1 reverts the imap module
to 4.0.3 behavior, without reintroducing the buffer overflow.

[Time-line]
20010226 Draft v0.1
20010226 Sent to Andi Gutmans (PHP) and  <security@horde.org> (IMP)
for comment
20010305 Release v1.0

[Disclaimer]
THE INFORMATION CONTAINED IN THIS ADVISORY IS BELIEVED TO BE ACCURATE,
BUT NO REPRESENTATION OR WARRANTY IS GIVEN, EXPRESS OR IMPLIED, AS TO
ITS ACCURACY OR COMPLETENESS. NEITHER THE AUTHOR NOR THE PUBLISHER
ACCEPTS ANY LIABILITY WHATSOEVER FOR ANY DIRECT, INDIRECT OR
CONSEQUENTIAL LOSS OR DAMAGE ARISING IN ANY WAY FROM ANY USE OF, OR
RELIANCE PLACED ON THIS INFORMATION FOR ANY PURPOSE. THIS ADVISORY MAY
BE REDISTRIBUTED PROVIDED THAT NO FEE IS ASSIGNED AND THAT THE
ADVISORY IS NOT MODIFIED IN ANY WAY.
(6174147) ------------------------------------------
Bilaga (text/plain) i text 6174148
6174148 2001-03-05 13:15 +0000  /61 rader/ pre <pre@GEEKGANG.CO.UK>
Bilagans filnamn: "gsa2001-01.diff"
Importerad: 2001-03-05  21:30  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: pre@GEEKGANG.CO.UK
Mottagare: Bugtraq (import) <15739>
Bilaga (text/plain) till text 6174147
Ärende: Bilaga (gsa2001-01.diff) till: [GSA2001-01] PHP IMAP overflow fix problems
------------------------------------------------------------
diff -ru php-4.0.4pl1/ext/imap/php_imap.c
php-4.0.4pl1-patched/ext/imap/php_imap.c
--- php-4.0.4pl1/ext/imap/php_imap.c	Wed Oct 25 18:43:52 2000
+++ php-4.0.4pl1-patched/ext/imap/php_imap.c	Mon Feb 26 13:17:08 2001
@@ -371,8 +371,8 @@

 static void php_imap_init_globals(zend_imap_globals *imap_globals)
 {
-	imap_globals->imap_user=NIL;
-	imap_globals->imap_password=NIL;
+	imap_globals->imap_user[0] = 0;
+	imap_globals->imap_password[0] = 0;
 	imap_globals->imap_folders=NIL;
 	imap_globals->imap_sfolders=NIL;
 	imap_globals->imap_alertstack=NIL;
@@ -633,8 +633,11 @@
 		}
 	}

-	IMAPG(imap_user)     = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user));
-	IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd),
Z_STRLEN_PP(passwd));
+	strncpy(IMAPG(imap_user), Z_STRVAL_PP(user), IMAPSTRLEN);
+	strncpy(IMAPG(imap_password), Z_STRVAL_PP(passwd),
IMAPSTRLEN);
+
+ 	IMAPG(imap_user)[IMAPSTRLEN-1] = 0;
+	IMAPG(imap_password)[IMAPSTRLEN-1] = 0;
 	
 #ifdef OP_RELOGIN
 	/* AJS: persistent connection handling */
@@ -766,8 +769,6 @@
 	} else {
 #endif
 		imap_stream = mail_open(NIL, Z_STRVAL_PP(mailbox),
flags);
-		efree(IMAPG(imap_user));
-		efree(IMAPG(imap_password));

 		if (imap_stream == NIL) {
 			php_error(E_WARNING, "Couldn't open stream
%s\n", (*mailbox)->value.str.val); diff -ru
php-4.0.4pl1/ext/imap/php_imap.h
php-4.0.4pl1-patched/ext/imap/php_imap.h
--- php-4.0.4pl1/ext/imap/php_imap.h	Tue Oct 17 16:42:05 2000
+++ php-4.0.4pl1-patched/ext/imap/php_imap.h	Mon Feb 26 13:16:11 2001
@@ -13,6 +13,7 @@
 extern zend_module_entry imap_module_entry;
 #define imap_module_ptr &imap_module_entry

+#define IMAPSTRLEN 80

 /* Data types */

@@ -140,8 +141,8 @@
 PHP_FUNCTION(imap_mime_header_decode);

 ZEND_BEGIN_MODULE_GLOBALS(imap)
-	char *imap_user;
-	char *imap_password;
+	char imap_user[IMAPSTRLEN];
+	char imap_password[IMAPSTRLEN];
 	STRINGLIST *imap_folders;
 	STRINGLIST *imap_sfolders;
 	STRINGLIST *imap_alertstack;
(6174148) --------------------------------(Ombruten)

6179683 2001-03-06 09:56 +0000  /19 rader/ Anil Madhavapeddy <anil@RECOIL.ORG>
Sänt av: joel@lysator.liu.se
Importerad: 2001-03-06  19:13  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: anil@RECOIL.ORG
Mottagare: Bugtraq (import) <15767>
Ärende: Re: [GSA2001-01] PHP IMAP overflow fix problems
------------------------------------------------------------
Quoting pre <pre@GEEKGANG.CO.UK>:

>
> This issue appears to be fixed in the current CVS version of PHP (I
> haven't tested it, just looked at the code).
>
> The gsa2001-01.diff patch against php-4.0.4pl1 reverts the imap module
> to 4.0.3 behavior, without reintroducing the buffer overflow.
>

Attached is a patch against php-4.0.4pl1 (backported from php-cvs),
which cures the problem without imposing 80-character limits or using
static buffers.

Just committed it to the OpenBSD-current port of PHP4.  Thanks
max@horde.org for testing under Linux.

--
Anil Madhavapeddy, <anil@recoil.org>
(6179683) --------------------------------(Ombruten)
Bilaga (text/plain) i text 6179684

6179684 2001-03-06 09:56 +0000  /89 rader/ Anil Madhavapeddy <anil@RECOIL.ORG>
Bilagans filnamn: "patch-ext_imap_php_imap_c"
Importerad: 2001-03-06  19:13  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: anil@RECOIL.ORG
Mottagare: Bugtraq (import) <15768>
Bilaga (text/plain) till text 6179683
Ärende: Bilaga (patch-ext_imap_php_imap_c) till: Re: [GSA2001-01] PHP IMAP overflow fix problems
------------------------------------------------------------
--- ext/imap/php_imap.c.orig	Tue Mar  6 09:22:17 2001
+++ ext/imap/php_imap.c	Tue Mar  6 09:24:10 2001
@@ -25,7 +25,7 @@
    | PHP 4.0 updates:  Zeev Suraski <zeev@zend.com>                       |
    +----------------------------------------------------------------------+
  */
-/* $Id: php_imap.c,v 1.50 2000/10/25 17:43:52 andrei Exp $ */
+/* $Id: php_imap.c,v 1.57 2001/02/21 20:33:46 thies Exp $ */

 #define IMAP41

@@ -183,7 +183,19 @@
 void mail_close_it(zend_rsrc_list_entry *rsrc)
 {
 	pils *imap_le_struct = (pils *)rsrc->ptr;
+	IMAPLS_FETCH();
+
 	mail_close_full(imap_le_struct->imap_stream,
imap_le_struct->flags);
+
+	if (IMAPG(imap_user)) {
+		efree(IMAPG(imap_user));
+		IMAPG(imap_user) = 0;
+	}
+	if (IMAPG(imap_password)) {
+		efree(IMAPG(imap_password));
+		IMAPG(imap_password) = 0;
+	}
+
 	efree(imap_le_struct);
 }

@@ -633,6 +645,14 @@
 		}
 	}

+	if (IMAPG(imap_user)) {
+		efree(IMAPG(imap_user));
+	}
+
+	if (IMAPG(imap_password)) {
+		efree(IMAPG(imap_password));
+	}
+
 	IMAPG(imap_user)     = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user));
 	IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd));
 	
@@ -712,6 +732,8 @@
 				}
  			}
 			efree(hashed_details);
+			efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
+			efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
 			RETURN_FALSE;
 		}

@@ -721,6 +743,8 @@
 			node = malloc(sizeof(pils));
 			if (node == NULL) {
 				efree(hashed_details);
+				efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
+				efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
 				RETURN_FALSE;
 			}

@@ -757,6 +781,8 @@

 			free(headp);
 			efree(hashed_details);
+			efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
+			efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
  			RETURN_FALSE;
 		}

@@ -766,11 +792,11 @@
 	} else {
 #endif
 		imap_stream = mail_open(NIL, Z_STRVAL_PP(mailbox),
flags);
-		efree(IMAPG(imap_user));
-		efree(IMAPG(imap_password));

 		if (imap_stream == NIL) {
 			php_error(E_WARNING, "Couldn't open stream
%s\n", (*mailbox)->value.str.val);
+			efree(IMAPG(imap_user)); IMAPG(imap_user) = 0;
+			efree(IMAPG(imap_password)); IMAPG(imap_password) = 0;
 			RETURN_FALSE;
 		}
(6179684) --------------------------------(Ombruten)