php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48400 imap crashes when closing stream opened with OP_PROTOTYPE option
Submitted: 2009-05-26 14:04 UTC Modified: 2011-02-02 21:23 UTC
From: dkelsey at uk dot ibm dot com Assigned: -
Status: Closed Package: IMAP related
PHP Version: 5.*, 6CVS (2009-05-26) OS: *
Private report: No CVE-ID:
 [2009-05-26 14:04 UTC] dkelsey at uk dot ibm dot com
Description:
------------
gpf occurs in the following simple script for imap
This looks similar to a bug that was flagged as bogus in 2005
http://bugs.php.net/bug.php?id=33457
then followed on at 
http://bugs.php.net/bug.php?id=33464

note that upgrading to imap-2007b doesn't resolve the issue.



Reproduce code:
---------------
<?php
$server   = '{localhost/norsh}';
$default_mailbox = $server . "INBOX";
$domain = "something.com";
$admin_user = "webmaster"; // a user with admin access 
$username = "$admin_user@$domain";
$password = 'p4ssw0rd';
$n_retries = 3;
var_dump($imap_stream = imap_open($server, $username, $password, OP_PROTOTYPE, $n_retries) );
imap_close($imap_stream);
?>

Actual result:
--------------
*** glibc detected *** /home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php: free(): invalid pointer: 0xb7ec97c0 *** 
======= Backtrace: =========
/lib/libc.so.6[0xb77ec851]
/lib/libc.so.6(__libc_free+0x84)[0xb77edeb4]
/usr/lib/libc-client.so.2004g_suse(fs_give+0x58)[0xb7ea2a88]
/usr/lib/libc-client.so.2004g_suse(mail_close_full+0xea)[0xb7e6fb1a]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php[0x8132ccd]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(list_entry_destructor+0x82)[0x8302b22]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(zend_hash_del_key_or_index+0x1f4)[0x8301074]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(_zend_list_delete+0x6c)[0x8302d6c]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(zif_imap_close+0xa4)[0x813b294]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php[0x831eff8]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(execute+0x12d)[0x8313acd]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(zend_execute_scripts+0x152)[0x82f63e2]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(php_execute_script+0x1c3)[0x82b5463]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php(main+0x1357)[0x8372c17]
/lib/libc.so.6(__libc_start_main+0xdc)[0xb779e87c]
/home/cruiseco/cruisebuilds/phptreport/php52/build_under_test/sapi/cli/php[0x8091a71]


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-26 19:59 UTC] jani@php.net
Considering this crashes also test.c:

#include "mail.h"

void mm_searched (MAILSTREAM *stream,unsigned long number){}
void mm_exists (MAILSTREAM *stream,unsigned long number){}
void mm_expunged (MAILSTREAM *stream,unsigned long number){}
void mm_flags (MAILSTREAM *stream,unsigned long number){}
void mm_notify (MAILSTREAM *stream,char *string,long errflg){}
void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes){}
void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes){}
void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status){}
void mm_log (char *string,long errflg){}
void mm_dlog (char *string){}
void mm_login (NETMBX *mb,char *user,char *pwd,long trial){}
void mm_critical (MAILSTREAM *stream){}
void mm_nocritical (MAILSTREAM *stream){}
long mm_diskerror (MAILSTREAM *stream,long errcode,long serious){}
void mm_fatal (char *string){}

int main(void) 
{
        MAILSTREAM *imap_stream;

        mail_link (&imapdriver);
        imap_stream = mail_open(NIL, "{localhost}", OP_PROTOTYPE);
        mail_close_full(imap_stream, 0);
}

# gcc -g -lc-client -I/usr/include/imap/ test.c -o test
# ./test
*** glibc detected *** ./test: free(): invalid pointer: 0x0063e260 ***
======= Backtrace: =========
/lib/libc.so.6[0xa7c3a4]
/lib/libc.so.6(cfree+0x96)[0xa7e356]
/usr/lib/libc-client.so.2007(fs_give+0x55)[0x546174]
/usr/lib/libc-client.so.2007(mail_close_full+0xed)[0x557e5d]
./test[0x80487f1]
/lib/libc.so.6(__libc_start_main+0xe5)[0xa236e5]

---

This quite clearly shows it's not a PHP bug.
 [2009-07-02 06:25 UTC] dkelsey at uk dot ibm dot com
I sent an email to the c-client mailing list and the response I got states clearly that it is a php problem as php is not using the mail apis correctly. Here is the response

--------------------------------------------------------------------
Hi Dave -

This is not a bug.  Rather, you have misunderstood some important points.

There are three issues with your sample program.

[1] You SHOULD include c-client.h, and not mail.h directly.  mail.h has 
most, but not all, of the consumer API definitions and prototypes.

[2] You MUST (repeat, MUST!!) include linkage.c at the start of your 
main() function instead of calling mail_link() directly.

[3] A prototype stream is not something that can be given to 
mail_close_full().

Without knowing why you are opening a prototype stream, it appears to me 
that you do not understand what a prototype stream is and how/why it is 
used; especially since this is an IMAP prototype stream, something which 
is almost completely useless except for internal c-client purposes.

A prototype stream is not a stream.  The closest analog to a prototype 
stream would be a factory object or class definition.  Internally, a 
prototype stream is simply a pointer to a static area of constant memory 
that has the dtb for that driver.

Prototype streams have VERY limited use to API consumers.  The primary 
consumer use is that of a local filesystem format prototype stream as an 
argument to mail_create() to force the created mailbox to be in that 
format.  However, that use is deprecated in favor of the #driver.???/ 
prefix; e.g.,
 		 mail_create (NIL,"#driver.mix/newbox");
is the preferred and more modern way of doing
 		 mail_create (mail_open (NIL,existingmixmailbox,OP_PROTOTYPE),"newbox");

The prototype stream method is the way to create a new local filesystem 
mailbox of the same format as an existing local filesystem mailbox, as 
opposed to a specified format via the #driver.???/ syntax .  This is 
therefore the 99% reason why any API consumer would use a prototype 
stream.

Your use may be in the remaining 1% (it would have to be, given that it's 
an IMAP prototype stream), but I suspect that it's really a case of your 
not understanding what you are doing.

Getting back to the subject at hand; since it is a factory object (or 
class definition), it is inappropriate to call non-factory methods on it. 
For most API consumers, other than mail_create() with a local filesystem 
driver prototype, the remaining uses are power tools for master sorcerers.

mail_close() and mail_close_full() are completely inappropriate methods to 
use with a prototype stream, even for a master sorcerer.  A prototype 
stream is not a stream, and is not something that can be closed.  When you 
are finished with a prototype stream, you just drop the pointer.

-- Mark --
--------------------------------------------------------------------
From the response, maybe the best solution is to just remove to OP_PROTOTYPE option, but the response does seem to indicate there could be other issues hiding away.
 [2009-07-02 11:37 UTC] dkelsey@php.net
re-opening the original bug as new bug raised was closed a bogus.
 [2009-07-26 12:13 UTC] jani@php.net
This is really funny. Why can't he add some checks in those funcs that 
they won't do anything if one passes them a prototype stream? I guess we 
need to cover that as well. And not do try closing those streams then. 
 [2009-08-03 13:02 UTC] svn@php.net
Automatic comment from SVN on behalf of jani
Revision: http://svn.php.net/viewvc/?view=revision&revision=286732
Log: - Fixed bug #48400 (imap crashes when closing stream opened with OP_PROTOTYPE flag)
 [2009-08-03 13:03 UTC] jani@php.net
This bug has been fixed in SVN.

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.


 [2011-02-02 21:23 UTC] jani@php.net
-Assigned To: jani +Assigned To: -
 [2011-02-02 21:23 UTC] jani@php.net
-Assigned To: - +Assigned To: jani
 [2011-02-02 21:23 UTC] jani@php.net
-Assigned To: jani +Assigned To: -
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 14:02:33 2014 UTC