php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29431 segfault using stream_* with UDP
Submitted: 2004-07-28 17:31 UTC Modified: 2004-07-31 13:43 UTC
From: [email protected] Assigned:
Status: Closed Package: Network related
PHP Version: 5.1.0-cvs OS: Linux 2.4
Private report: No CVE-ID: None
 [2004-07-28 17:31 UTC] [email protected]
Description:
------------
PHP 5 HEAD segfaults with the given code.
Below are URLs with valgrind/gdb output.

Reproduce code:
---------------
<?
$socket = stream_socket_server("udp://127.0.0.1:13", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket)
	die("$errstr ($errno)");

do {
   $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
   stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
} while ($pkt !== false);

?>

Actual result:
--------------
http://testes.aborla.net/gdb.txt
http://testes.aborla.net/out.pid7736

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-07-29 01:00 UTC] [email protected]
Does it segfault if you disable the sockets extension?
(Looking into your script now, but the valgrind output indicates that ext/sockets is still a bad choice)
 [2004-07-29 01:31 UTC] [email protected]
Fixed in HEAD.
 [2004-07-30 18:13 UTC] [email protected]
It doesn't segfault, but... doesn't work.
I think stream_socket_recvfrom() ins't populating $peer


"Warning: stream_socket_sendto()]: Invalid argument in /transfer/a.php on line 11"


gdb output:

Program received signal SIGINT, Interrupt.
0x4037e6c2 in select () from /lib/libc.so.6
(gdb) bt
#0  0x4037e6c2 in select () from /lib/libc.so.6
#1  0x082beddc in __JCR_LIST__ ()
#2  0xbfffd2b8 in ?? ()
#3  0xbfffd340 in ?? ()
#4  0x081c9c3d in php_sock_stream_wait_for_data (stream=0x836e95c,
    sock=0x83640cc) at /cvs/php-src/main/streams/xp_socket.c:100
#5  0x081c9c8f in php_sockop_read (stream=0x836e95c, buf=0x836eb14 "",
    count=8192) at /cvs/php-src/main/streams/xp_socket.c:120
#6  0x081c191e in php_stream_fill_read_buffer (stream=0x836e95c, size=1)
    at /cvs/php-src/main/streams/streams.c:530
#7  0x081c1c34 in _php_stream_read (stream=0x836e95c, buf=0x836412c "", size=1)
    at /cvs/php-src/main/streams/streams.c:573
#8  0x081c998f in php_stream_xport_recvfrom (stream=0x836e95c,
    buf=0x836412c "", buflen=1, flags=0, addr=0x0, addrlen=0xfffffdfe,
    textaddr=0x836ea44, textaddrlen=0xfffffdfe)
    at /cvs/php-src/main/streams/transports.c:391
#9  0x081a4fee in zif_stream_socket_recvfrom (ht=4, return_value=0x8370b7c,
    this_ptr=0x0, return_value_used=1)
    at /cvs/php-src/ext/standard/streamsfuncs.c:328
#10 0x082096d9 in zend_do_fcall_common_helper (execute_data=0xbfffd630,
    opline=0x837322c, op_array=0x836e88c)
    at /cvs/php-src/Zend/zend_execute.c:2699
#11 0x0820983a in zend_do_fcall_handler (execute_data=0xbfffd630,
    opline=0x837322c, op_array=0x836e88c)
    at /cvs/php-src/Zend/zend_execute.c:2831
#12 0x08206068 in execute (op_array=0x836e88c)
    at /cvs/php-src/Zend/zend_execute.c:1391
#13 0x081e9dca in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /cvs/php-src/Zend/zend.c:1068
#14 0x081b4440 in php_execute_script (primary_file=0xbffffa00)
    at /cvs/php-src/main/main.c:1631
#15 0x08210f80 in main (argc=2, argv=0xbffffa94)
    at /cvs/php-src/sapi/cli/php_cli.c:943
 [2004-07-30 19:23 UTC] [email protected]
Works flawlessly here; are you sure you're running head?

udp.php:
<?php
$socket = stream_socket_server("udp://127.0.0.1:1113", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket)
       die("$errstr ($errno)");

do {
  $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);
  print_r($pkt);
  print_r($peer);
  stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer);
} while ($pkt !== false);

?>

% php udp.php &
% php -r '$f = fsockopen("udp://127.0.0.1", 1113); fwrite($f, 'x'); var_dump(fgets($f));'


 [2004-07-30 21:05 UTC] [email protected]
Yep!

I've done a cvsclean (and a cvs update) and re-compiled everything, and still get the same backtrace/error.
 [2004-07-31 12:06 UTC] [email protected]
Please try the script I posted.
Paste it's output.
If it doesn't work, run it using:

strace -e trace=net php udp.php

and paste that output too.
 [2004-07-31 12:25 UTC] [email protected]
# strace -e trace=network php udp.php

socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = -1 EAFNOSUPPORT (Address family not supported by protocol)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(1113), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recv(3, "x", 8192, 0)                   = 1
xsendto(3, "Sat Jul 31 10:34:20 2004\r\n", 26, 0, {sa_family=0x3032 /* AF_??? */
, sa_data="04\0\0\0\0\24\325\377\277\2568)@"}, 0) = -1 EINVAL (Invalid argument)


Warning: stream_socket_sendto() [/manual/function.stream-socket-sendto.html]: In
valid argument
 in /transfer/udp.php on line 10



It just outputs 'x', so $peer is empty.
 [2004-07-31 13:03 UTC] [email protected]
Looks like I forgot to commit some changes;
should be fixed now in both HEAD and 5.0 branches.
 [2004-07-31 13:16 UTC] [email protected]
The problem is fixed! Thanks!!!

But valgrind still complains... Not sure if it's related with streams, but:

==14229== 18 bytes in 1 blocks are still reachable in loss record 1 of 3
==14229==    at 0x40026BB2: malloc (vg_replace_malloc.c:153)
==14229==    by 0x4058638B: inet_ntoa (in /lib/libc-2.3.3.so)
==14229==    by 0x81BE8BE: php_network_populate_name_from_sockaddr (network.c:593)
==14229==    by 0x81CA06C: php_sockop_set_option (xp_socket.c:223)
==14229==    by 0x81C27BB: _php_stream_set_option (streams.c:1110)
==14229==    by 0x81C988A: php_stream_xport_recvfrom (transports.c:433)
==14229==    by 0x81A4FED: zif_stream_socket_recvfrom (streamsfuncs.c:328)
==14229==    by 0x8209810: zend_do_fcall_common_helper (zend_execute.c:2699)
==14229==    by 0x82099FE: zend_do_fcall_handler (zend_execute.c:2831)
==14229==    by 0x8205FF7: execute (zend_execute.c:1391)
==14229==    by 0x81E9D59: zend_execute_scripts (zend.c:1068)
==14229==    by 0x81B443F: php_execute_script (main.c:1631)
==14229==    by 0x821118F: main (php_cli.c:943)
==14229==    by 0x404E1858: __libc_start_main (in /lib/libc-2.3.3.so)
==14229==    by 0x8080550: (within /usr/local/bin/php)
==14229== 
==14229== 
==14229== 100 bytes in 1 blocks are still reachable in loss record 2 of 3
==14229==    at 0x40026BB2: malloc (vg_replace_malloc.c:153)
==14229==    by 0x81D353B: yy_flex_alloc (zend_language_scanner.c:6260)
==14229==    by 0x81D33DB: yy_push_state (zend_language_scanner.c:6149)
==14229==    by 0x81D0B02: lex_scan (zend_language_scanner.l:1152)
==14229==    by 0x81DDE90: zendlex (zend_compile.c:3682)
==14229==    by 0x81CEE8C: zendparse (zend_language_parser.c:2632)
==14229==    by 0x81CF2F2: compile_file (zend_language_scanner.l:375)
==14229==    by 0x81E9D21: zend_execute_scripts (zend.c:1064)
==14229==    by 0x81B443F: php_execute_script (main.c:1631)
==14229==    by 0x821118F: main (php_cli.c:943)
==14229==    by 0x404E1858: __libc_start_main (in /lib/libc-2.3.3.so)
==14229==    by 0x8080550: (within /usr/local/bin/php)
 [2004-07-31 13:43 UTC] [email protected]
Nope, not a PHP; that indicates that inet_ntoa has a memory leak.  However:

man inet_ntoa -->
The inet_ntoa() function converts the Internet host address
in given in network byte order to a string in standard
numbers-and-dots notation.  The string is returned in a
statically allocated buffer, which  subsequent  calls  will
overwrite.

It's not PHP's responsibility to clean that up, and most likely it's something that valgrind should suppress anyway, and its only 18 bytes ;-)
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Dec 31 03:00:01 2025 UTC