Bug #78231 [Com]: Segmentation fault upon stream_socket_accept of exported socket-to-stream
| From: | asmqb7 at gmail dot com | Date: | Fri, 05 Jul 2019 10:41:56 +0000 |
| Subject: | Bug #78231 [Com]: Segmentation fault upon stream_socket_accept of exported socket-to-stream | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-221640@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78231&edit=1
ID: 78231
Comment by: asmqb7 at gmail dot com
Reported by: asmqb7 at gmail dot com
Summary: Segmentation fault upon stream_socket_accept of
exported socket-to-stream
Status: Closed
Type: Bug
Package: Sockets related
Operating System: Linux
PHP Version: 7.2.20, 7.3.6
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
Wow - that was a very quick fix!
(Could not possibly have expected it was from the openssl extension checking if tcp_nodelay was
enabled :) interesting.)
Good catch about the missing
socket_listen($socket), which should have gone immediately
after the socket_bind(). Didn't realize this because the segfault got in the way.
Also, my apologies for the unneeded edges in my initial bug report - my feathers were ruffled, but
not to the extent I let on.
Previous Comments:
------------------------------------------------------------------------
[2019-07-03 10:38:32] nikic@php.net
Segfault fixed... Note that the script is missing the listen step, so the accept will still fail.
------------------------------------------------------------------------
[2019-07-03 10:37:41] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0e48e35e0485bc6d6458a45ecab5b19a0c2ec001
Log: Fixed bug #78231
------------------------------------------------------------------------
[2019-07-03 09:58:56] nikic@php.net
Confirming segfault, also on 7.2.
------------------------------------------------------------------------
[2019-06-29 06:05:40] asmqb7 at gmail dot com
Description:
------------
Due to lack of documentation about the fact that SO_REUSEADDR is unconditionally set when
stream_socket_server() is used, I thought I would need to use the socket_* functions to set the
option on a stream I'd already created.
I figured I could then export the newly-bound socket to a stream, and proceed from there without
needing to use any other socket_* functions, which I try to avoid using as I've been bitten by
the sockets extension in the past (other bugs etc).
Well, I'm not quite sure what I broke this time, but the attached test script segfaults on my
system with 100% consistency. I suspect the code path that handles "stream bound by the sockets
library, exported, then selected on by the streams subsystem" is probably un[der?]implemented.
It's not visible yet, but I added some info to the notes section at http://php.net/socket_set_option, which is what shows
up most prominently when googling SO_REUSEADDR in the context of PHP.
Test script:
---------------
<?php
$port = 55555;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
print '$socket: '; var_dump($socket);
print 'socket_bind(): ';
var_dump(socket_bind($socket, '127.0.0.1', $port));
$listening_fd = socket_export_stream($socket);
print 'socket_export_stream(): ';
var_dump($listening_fd);
for (;;) {
$read = $write = $except = [];
$read[] = $listening_fd;
stream_select($read, $write, $except, null);
foreach ($read as $fd) {
switch ($fd) {
case $listening_fd:
print "stream_socket_accept() on: "; var_dump($fd);
$new_fd = stream_socket_accept($fd);
}
}
}
Expected result:
----------------
For a stream exported from a socket to behave identically to a stream created by the streams
functionality, and particularly for untested codepaths to not cause runtime segfaults.
Actual result:
--------------
$socket: resource(4) of type (Socket)
socket_bind(): bool(true)
socket_export_stream(): resource(5) of type (stream)
stream_socket_accept() on: resource(5) of type (stream)
Program received signal SIGSEGV, Segmentation fault.
0x00005555558ce3b6 in php_stream_context_get_option ()
(gdb) bt
#0 0x00005555558ce3b6 in php_stream_context_get_option ()
#1 0x00005555556df1bc in ?? ()
#2 0x00005555558cc72d in _php_stream_set_option ()
#3 0x00005555558d6560 in php_stream_xport_accept ()
#4 0x0000555555884378 in ?? ()
#5 0x0000555555994a85 in execute_ex ()
#6 0x000055555599aaf6 in zend_execute ()
#7 0x00005555559136aa in zend_execute_scripts ()
#8 0x00005555558b35c9 in php_execute_script ()
#9 0x000055555599d0f6 in ?? ()
#10 0x000055555569e0a7 in ?? ()
#11 0x00007ffff72abce3 in __libc_start_
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78231&edit=1