| Bug #42862 | [PATCH] IMAP toolkit crash: rfc822.c legacy routine buffer overflow | ||||
|---|---|---|---|---|---|
| Submitted: | 5 Oct 2007 7:29am UTC | Modified: | 16 Oct 2008 4:24pm UTC | ||
| From: | Maylein at ub dot uni-heidelberg dot de | Assigned to: | pajoye | ||
| Status: | Closed | Category: | IMAP related | ||
| Version: | 5.2.6 | OS: | * | ||
| Votes: | 27 | Avg. Score: | 4.4 ± 0.9 | Reproduced: | 22 of 22 (100.0%) |
| Same Version: | 8 (36.4%) | Same OS: | 7 (31.8%) | ||
[5 Oct 2007 7:29am UTC] Maylein at ub dot uni-heidelberg dot de
[11 Oct 2007 8:20am UTC] Maylein at ub dot uni-heidelberg dot de
See also http://archives.devshed.com/forums/networking-100/new-message-writing-ro utines-in-imap-2005t-1639473.html
[4 Mar 2008 4:57pm UTC] sborrill at precedence dot co dot uk
php_imap.c uses rfc822_write_address() which, with imap-uw sources since
2005, limits the complete returned address list to 16383 bytes in length
irrespective of the size of the buffer you pass into it (you don't pass
the length, so it can't know the actual size).
This means that if you have a large address lists in your To: or Cc:
headers, that would expand to more than 16383 characters, PHP will
core-dump with SIGABRT.
This affects PHP HEAD too.
rfc822_write_address is deprecated:
* WARNING: These routines are for compatibility with old software
only.
*
* Their use in new software is to be avoided.
*
* These interfaces do not provide satisfactory buffer checking. In
* versions of c-client prior to imap-2005, they did not provide any
* buffer checking at all.
The fix is to use rfc822_output_address_list().
Patch below (against 5.2.5):
--- php_imap.c.orig 2007-07-31 01:31:10.000000000 +0100
+++ php_imap.c 2008-03-04 17:48:30.000000000 +0000
@@ -70,6 +70,7 @@
static void _php_imap_add_body(zval *arg, BODY *body TSRMLS_DC);
static void _php_imap_parse_address(ADDRESS *addresslist, char
**fulladdress, zval *paddress TSRMLS_DC);
static int _php_imap_address_size(ADDRESS *addresslist);
+static void _php_rfc822_write_address_len (char *dest, ADDRESS *adr,
int len);
/* the gets we use */
static char *php_mail_gets(readfn_t f, void *stream, unsigned long
size, GETS_DATA *md);
@@ -2137,7 +2138,7 @@
}
string[0]='\0';
- rfc822_write_address(string, addr);
+ _php_rfc822_write_address_len(string, addr, sizeof(string));
RETVAL_STRING(string, 1);
}
/* }}} */
@@ -2906,13 +2907,13 @@
if (env->from && _php_imap_address_size(env->from) < MAILTMPLEN) {
env->from->next=NULL;
address[0] = '\0';
- rfc822_write_address(address, env->from);
+ _php_rfc822_write_address_len(address, env->from,
sizeof(address));
add_property_string(myoverview, "from", address, 1);
}
if (env->to && _php_imap_address_size(env->to) < MAILTMPLEN) {
env->to->next = NULL;
address[0] = '\0';
- rfc822_write_address(address, env->to);
+ _php_rfc822_write_address_len(address, env->to, sizeof(address));
add_property_string(myoverview, "to", address, 1);
}
if (env->date) {
@@ -3883,6 +3884,34 @@
/* }}} */
+/* {{{ _php_rfc822_soutr
+ */
+static long _php_rfc822_soutr (void *stream,char *string)
+{
+ return NIL;
+}
+
+/* }}} */
+
+
+/* {{{ _php_rfc822_write_address_len
+ */
+static void _php_rfc822_write_address_len ( char *dest, ADDRESS *adr,
int len)
+{
+ RFC822BUFFER buf;
+
+ buf.beg = dest;
+ buf.cur = buf.beg;
+ buf.end = buf.beg + len - 1;
+ buf.s = NIL;
+ buf.f = _php_rfc822_soutr;
+ rfc822_output_address_list (&buf, adr, 0, NIL);
+ *buf.cur = '\0';
+}
+
+/* }}} */
+
+
/* {{{ _php_imap_parse_address
*/
static void _php_imap_parse_address (ADDRESS *addresslist, char
**fulladdress, zval *paddress TSRMLS_DC)
@@ -3897,7 +3926,7 @@
if ((len = _php_imap_address_size(addresstmp))) {
tmpstr = (char *) pemalloc(len + 1, 1);
tmpstr[0] = '\0';
- rfc822_write_address(tmpstr, addresstmp);
+ _php_rfc822_write_address_len(tmpstr, addresstmp, len);
*fulladdress = tmpstr;
} else {
*fulladdress = NULL;
[3 Apr 2008 9:55pm UTC] pubear at u dot washington dot edu
I am using imap c-client 2007a with php-5.2.5. I am working with an extensively modified version of: http://migrationtool.sourceforge.net I ran into this issue migrating people's mailboxes in Exchange Server. I wanted to confirm that the patch submitted by sborrill at precedence dot co dot uk appears to have fixed the buffer overflow bug. Thank you very much.
[27 May 2008 1:06pm UTC] falon at csi dot it
I use Horde Groupware Webmail Edition 1.0.6 with Apache/1.3.41 (Unix) PHP/5.2.5 mod_ssl/2.8.31 OpenSSL/0.9.8g. I had the same bug. I tried sborril patch: it fix the problem also in my environment. I appreciate if could be added to next release of php. Regards
[18 Jun 2008 5:43pm UTC] hoffie at gentoo dot org
Over 7 months and two releases have passed, yet no developer even commented on this *security* issue (according to the c-client devs). So what's up with this, are there any problems with the patch? If yes, would you mind pointing them out, so that one can try to fix them?
[24 Jun 2008 10:54am UTC] hoffie at gentoo dot org
This is CVE-2008-2829.
[8 Jul 2008 6:27pm UTC] david at blue-labs dot org
please fix 008_imap-bufferoverflows.patch to include the typedef for
RFC822BUFFER.
/* Output buffering for RFC [2]822 */
typedef long (*soutr_t) (void *stream,char *string);
typedef struct rfc822buffer {
soutr_t f; /* I/O flush routine */
void *s; /* stream for I/O routine */
char *beg; /* start of buffer */
char *cur; /* current buffer pointer */
char *end; /* end of buffer */
} RFC822BUFFER;
[21 Jul 2008 9:48pm UTC] pajoye@php.net
I will give it some love while working on the imap lib.
[14 Oct 2008 12:38am UTC] stas@php.net
Looking at the current code, it looks like there's no actual overflow, but rfc822_write_address is limited so the abort happens. I am not seeing code path that would lead to rfc822_write_address writing more data than buffer size, unless I misunderstand how _php_imap_address_size works. Is this impression correct? If so, we still need to fix it since abort() is a nasty things, but it doesn't seem to be a security issue.
[14 Oct 2008 6:48pm UTC] stas@php.net
Also, what is the requirement for using rfc822_output_address_list - what is minimal c-client lib version that has it supported?
[16 Oct 2008 4:24pm UTC] dmitry@php.net
This bug has been fixed in CVS. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better.
