Hey Rasmus

2013/8/3 Rasmus Lerdorf <ras...@lerdorf.com>:
> Hey Johannes, could you take a look at:
>
> https://gist.github.com/anonymous/6143477
>
> You can reproduce in 5.5 with:
>
> sapi/cli/php ext/mysqli/tests/mysqli_poll_kill.php
>
> main/streams/cast.c:306 is:
>
> if (php_stream_is_filtered(stream)) {
>
> but php_stream_is_filtered is just a macro that isn't expecting stream
> to be null and you get the segfault there because it is trying to
> dereference it. We could just add a null check, of course, but I think
> the problem is in mysqlnd. mysqlnd_stream_array_to_fd_set() shouldn't be
> trying to cast null streams.

I've attached a patch that should check for a NULL stream, it works as follows:

mysqlnd_stream_array_to_fd_set() (&
mysqlnd_stream_array_from_fd_set()) calls the get_stream method, which
may return NULL, previously it was directly passed to
php_stream_cast(), and not checked prior to that.

However, I did not look into the mysqli_poll function, which may not
properly set a stream or something in that way, so this patch *should*
be just getting rid of the noise. I'm saying "should" as I did not
have the time to configure a build env from where I currently am
located as well as I'm rusty =(

Patch is attached.



-- 
regards,

Kalle Sommer Nielsen
ka...@php.net
diff --git 
"a/C:\\Users\\Kalle\\AppData\\Local\\Temp\\TortoiseGit\\mysA3C4.tmp\\mysqlnd-b48f7e0-left.c"
 "b/C:\\dev\\php-src\\ext\\mysqlnd\\mysqlnd.c"
index 1a89869..082c66a 100644
--- 
"a/C:\\Users\\Kalle\\AppData\\Local\\Temp\\TortoiseGit\\mysA3C4.tmp\\mysqlnd-b48f7e0-left.c"
+++ "b/C:\\dev\\php-src\\ext\\mysqlnd\\mysqlnd.c"
@@ -1261,6 +1261,7 @@ MYSQLND ** 
mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array TSRMLS
 static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, 
php_socket_t * max_fd TSRMLS_DC)
 {
        php_socket_t this_fd;
+       php_stream stream;
        int cnt = 0;
        MYSQLND **p = conn_array;
 
@@ -1270,7 +1271,9 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** 
conn_array, fd_set * fds, p
                 * when casting.  It is only used here so that the buffered 
data warning
                 * is not displayed.
                 * */
-               if (SUCCESS == 
php_stream_cast((*p)->data->net->data->m.get_stream((*p)->data->net TSRMLS_CC), 
PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
+               stream = (*p)->data->net->data->m.get_stream((*p)->data->net 
TSRMLS_CC);
+
+               if (stream && SUCCESS == php_stream_cast(stream, 
PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
                                                                                
(void*)&this_fd, 1) && this_fd >= 0) {
 
                        PHP_SAFE_FD_SET(this_fd, fds);
@@ -1288,6 +1291,7 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** 
conn_array, fd_set * fds, p
 static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * 
fds TSRMLS_DC)
 {
        php_socket_t this_fd;
+       php_stream stream;
        int ret = 0;
        zend_bool disproportion = FALSE;
 
@@ -1295,7 +1299,9 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** 
conn_array, fd_set * fds
        MYSQLND **fwd = conn_array, **bckwd = conn_array;
 
        while (*fwd) {
-               if (SUCCESS == 
php_stream_cast((*fwd)->data->net->data->m.get_stream((*fwd)->data->net 
TSRMLS_CC), PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
+               stream = 
(*fwd)->data->net->data->m.get_stream((*fwd)->data->net TSRMLS_CC);
+
+               if (SUCCESS == php_stream_cast(stream, 
PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
                                                                                
(void*)&this_fd, 1) && this_fd >= 0) {
                        if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
                                if (disproportion) {
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to