ID:               26909
 Updated by:       [EMAIL PROTECTED]
 Reported By:      kristijonas dot siaulys at delfi dot lt
-Status:           Open
+Status:           Closed
 Bug Type:         Reproducible crash
 Operating System: FreeBSD 5.1, RedHat 7.3
 PHP Version:      Irrelevant
 New Comment:

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.




Previous Comments:
------------------------------------------------------------------------

[2004-01-14 18:05:39] kristijonas dot siaulys at delfi dot lt

p.s. on Linux crash code is 'exit signal Segmentation fault (11)'
and the patch I've provided is diff'ed on PHP 4.3.4 but it should apply
on other versions too.

------------------------------------------------------------------------

[2004-01-14 14:32:53] kristijonas dot siaulys at delfi dot lt

Description:
------------
imap_mime_header_decode can't handle RFC2047 encoded strings where
encoding is not 'Q' or 'B' (qprint, base64).
If another letter is specified then Apache exits on signal 6. This is
due to usage of fs_give() where it shouldn't be.
The bug is located in ext/imap/php_imap.c.
As I've noticed all PHP versions suppoting imap_mime_header_decode
funcion have this bug.

Here is a fix patch:
--- ext/imap/php_imap.c.orig    Thu Sep  4 10:48:30 2003
+++ ext/imap/php_imap.c Wed Jan 14 19:23:09 2004
@@ -3511,6 +3511,7 @@
        char *string, *charset, encoding, *text, *decode;
        long charset_token, encoding_token, end_token, end, offset=0, i;
        unsigned long newlength;
+       int valid_encoding;
 
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) ==
FAILURE) {
                ZEND_WRONG_PARAM_COUNT();
@@ -3550,11 +3551,14 @@
                                                memcpy(text, &string[encoding_token + 
3], end_token -
(encoding_token + 3));  /* Extract text */
                                                text[end_token - (encoding_token + 3)] 
= 0x00;
                                                decode = text;
+                                               valid_encoding=0;
                                                if (encoding == 'q' || encoding == 
'Q') {       /* Decode 'q' encoded
data */
                                                        for(i=0; text[i] != 0x00; i++) 
if (text[i] == '_') text[i] = '
';      /* Replace all *_' with space. */
                                                        decode = (char 
*)rfc822_qprint((unsigned char *) text,
strlen(text), &newlength);
+                                                       valid_encoding=1;
                                                } else if (encoding == 'b' || encoding 
== 'B') {
                                                        decode = (char 
*)rfc822_base64((unsigned char *) text,
strlen(text), &newlength); /* Decode 'B' encoded data */
+                                                       valid_encoding=1;
                                                }
                                                if (decode == NULL) {
                                                        efree(charset);
@@ -3566,7 +3570,7 @@
                                                add_property_string(myobject, 
"charset", charset, 1);
                                                add_property_string(myobject, "text", 
decode, 1);
                                                
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), (void
*)&myobject, sizeof(zval *), NULL);
-                                               fs_give((void**)&decode);
+                                               if(valid_encoding) 
fs_give((void**)&decode);
                                                
                                                offset = end_token+2;
                                                for (i = 0; (string[offset + i] == ' 
') || (string[offset + i]
== 0x0a) || (string[offset + i] == 0x0d); i++);


Reproduce code:
---------------
imap_mime_header_decode("=?whatever?not_q_or_b?whatever?=");

As this function is mostly used in webmail systems to decode subjects,
by sending an email with malicious subject can make users mailbox
innacessible via that webmail application (as message subject listing
would crash apache).


Expected result:
----------------
I expect this function to decode text 'whatever' to 'whatever' and not
to crash Apache.
The code does that, but double 'free' at the end crashes Apache and no
resut is returned.

Actual result:
--------------
Apache child exited on signal 6.

This is beacuse such malformed string causes such code sequence (in
ext/imap/php_imap.c):
1. text = emalloc(size);
2. decoded = text;
3. fs_give(decoded);
4. efree(text);

notice two 'free' at the end.



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=26909&edit=1

Reply via email to