php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38649 NULL pointer leads to core dump in "php_stream_bucket_unlink()"
Submitted: 2006-08-30 06:05 UTC Modified: 2006-10-11 23:23 UTC
From: songmaqd at hotmail dot com Assigned: pollita (profile)
Status: Closed Package: Streams related
PHP Version: 5CVS-2006-08-30 (snap) OS: UNIX
Private report: No CVE-ID: None
 [2006-08-30 06:05 UTC] songmaqd at hotmail dot com
Description:
------------
In source file "main/streams/xp_socket.c", function "sock_sendto" need more strict condition evaluation in "if" judgement.

The reason is because PHP function "stream_socket_sendto" has an optional parameter "string address". When user omit this option, "addr" and "addrlen" is not initialized or valid. Since "addr" is a char pointer, if it is not initialized then its value is highly operation system dependent. We can not assume it is "NULL" or a invalid value not not "NULL". This leads core dump.

Problem code:
static inline int sock_sendto(php_netstream_data_t *sock, char *buf, size_t buflen, int flags,
		struct sockaddr *addr, socklen_t addrlen
		TSRMLS_DC)
{
	if (addr) {
		return sendto(sock->socket, buf, buflen, flags, addr, addrlen);
	}
	return send(sock->socket, buf, buflen, flags);
}

An possible fix example:
static inline int sock_sendto(php_netstream_data_t *sock, char *buf, size_t buflen, int flags,
		struct sockaddr *addr, socklen_t addrlen
		TSRMLS_DC)
{
	if (addr && (addrlen>0)) /*newly added*/{
		return sendto(sock->socket, buf, buflen, flags, addr, addrlen);
	}
	return send(sock->socket, buf, buflen, flags);
}



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-08-30 08:48 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2006-08-31 10:28 UTC] songmaqd at hotmail dot com
Here is the reproduce script:

1. At first run the belowing script as server process
<?php
$socket = stream_socket_server("tcp://localhost:8000", $errno, $errstr);
if (!$socket) {
 echo "$errstr ($errno)<br />\n";
} else {
        while(1){
                $conn = stream_socket_accept($socket);
                var_dump(fread($conn, 1024));
                stream_socket_sendto($conn, "The local time is ".date("n/j/Y g:i
 a"),STREAM_OOB);
        }
}
fclose($socket);
?>
2. Then run the following script in other shell as client process
<?php
$st = pfsockopen("tcp://localhost", 8000);
var_dump(stream_socket_get_name($st, false));
var_dump(stream_socket_get_name($st, true));
fwrite($st, "user:passwd");
var_dump(stream_socket_recvfrom($st, 1024));
?>

Note:
1. This bug can not be reproduced on Linux platform. My distro is SuSE 10.1. I can reproduce the bug on one certain UNIX platform.

2.The above script is for testing purpose and is deliberated written like that. It is not following the stream socket coding way.

3. Here is some debugger info.
**** ****
(gdb) b xp_socket.c:221
Breakpoint 1 at 0x8255cb6: file /home/sma/src/php-5.1.2/main/streams/xp_socket.c, line 221.
(gdb) run server.php
Starting program: /home/sma/src/php-5.1.2/sapi/cli/php server.php
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 5640)]
string(11) "user:passwd"
[Switching to Thread 16384 (LWP 5640)]

Breakpoint 1, php_sockop_set_option (stream=0x84a18f4, option=-1074674592, value=0, ptrparam=0xbff1c3b0)
    at /home/sma/src/php-5.1.2/main/streams/xp_socket.c:221
221             if (addr) {
(gdb) bt
#0  php_sockop_set_option (stream=0x84a18f4, option=-1074674592, value=0, ptrparam=0xbff1c3b0)
    at /home/sma/src/php-5.1.2/main/streams/xp_socket.c:221
#1  0x08256063 in php_tcp_sockop_set_option (stream=0x84a6a5c, option=7, value=-1074674592, ptrparam=0xbff1c3b0)
    at /home/sma/src/php-5.1.2/main/streams/xp_socket.c:735
#2  0x082494f5 in _php_stream_set_option (stream=0x84a6a5c, option=7, value=0, ptrparam=0xbff1c460)
    at /home/sma/src/php-5.1.2/main/streams/streams.c:1129
#3  0x08255634 in php_stream_xport_sendto (stream=0x84a6a5c, buf=0xbff1c460 "", buflen=3220292704, flags=1, addr=0x0, addrlen=3220292704)
    at /home/sma/src/php-5.1.2/main/streams/transports.c:481
#4  0x08224599 in zif_stream_socket_sendto (ht=-1074674592, return_value=0x84a699c, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/sma/src/php-5.1.2/ext/standard/streamsfuncs.c:328
#5  0x0829cad0 in zend_do_fcall_common_helper_SPEC (execute_data=0xbff1c6f0) at zend_vm_execute.h:192
#6  0x0829c388 in execute (op_array=0x84a17d4) at zend_vm_execute.h:92
#7  0x0827cab0 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/sma/src/php-5.1.2/Zend/zend.c:1101
#8  0x0823827d in php_execute_script (primary_file=0xbff1ec20) at /home/sma/src/php-5.1.2/main/main.c:1720
#9  0x082fe29f in main (argc=2, argv=0xbff1ecb4) at /home/sma/src/php-5.1.2/sapi/cli/php_cli.c:1077
(gdb) next
220     {
(gdb)
221             if (addr) {
(gdb)
222                     return sendto(sock->socket, buf, buflen, flags, addr, addrlen);
(gdb)
220     {
(gdb)

stacke backtrace "#3" clearly showed that "addr=0x0" and "addrlen" is an invalide value. But it still called "sendto(sock->socket, buf, buflen, flags, addr, addrlen);". Howeve "sendto" is highly platform dependent. It is not optimized.
 [2006-09-01 12:57 UTC] tony2001@php.net
Assigned to the maintainer.
 [2006-10-11 23:23 UTC] pollita@php.net
This bug has been fixed in CVS.

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.

Fix will appear in 5.2.0RC6 (though different from your suggested fix)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC