In testing PHP7 beyond just the default extensions, I am noticing that ext/imap is segfaulting on almost every test. I tracked it down to this code in ext/imap/php_imap.c:
/* {{{ imap_do_open */ static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) { char *mailbox, *user, *passwd; int mailbox_len, user_len, passwd_len; long retries = 0, flags = NIL, cl_flags = NIL; MAILSTREAM *imap_stream; pils *imap_le_struct; zval *params = NULL; int argc = ZEND_NUM_ARGS(); if (zend_parse_parameters(argc, "pss|lla", &mailbox, &mailbox_len, &user, &user_len, &passwd, &passwd_len, &flags, &retries, ¶ms) == FAILURE) { return; } ... /* local filename, need to perform open_basedir check */ if (mailbox[0] != '{' && php_check_open_basedir(mailbox)) { RETURN_FALSE; } The actual segfault is on the access to mailbox[0] because mailbox is a bogus pointer at this point and from userspace it is reproducable from cli with just: sapi/cli/php -r 'imap_open("host", "user", "password");' And here is where it gets mysterious. Looking at it with gdb, zend_parse_parameters is setting that mailbox char* to 0x7fff00000000 while both the user and passwd ptrs are fine. BUT, if I recompile ext/imap/php_imap.c using gcc -O3 the ptr is magically fine and no more segfaults. I suspected my gcc-4.8 on my Ubuntu laptop, so I built a completely clean Debian 7.8.0 box which defaults to gcc-4.7.2 and I see the exact same behaviour. segfaults under -O1/O2 but it is fine under -O0/O3. It is also fine from the PHP 5.6 tree even though the changes are mostly just removing TSRM and moving from zval** to zval* in a couple of places. Things I have tried. changed it from "p" to "s" and also from "p" to "S" and using a zend_string * instead. In both cases I got the same bogus address back from zpp. Right now I am trying to make sense of the generated assembly differences, but it is slow going. Since almost the same code works for PHP 5.6 and this is limited to just the imap extension, it seems more logical that something in the 5-6 to 7 changes is causing this and somehow -O3 optimizes its way around the problem. So, does anyone see a mistake in these changes? https://gist.github.com/anonymous/b92dbb17172e9bff5247 -Rasmus
signature.asc
Description: OpenPGP digital signature