diff options
-rw-r--r-- | ext/sockets/sockets.c | 2 | ||||
-rw-r--r-- | ext/sockets/tests/bug76839.phpt | 65 |
2 files changed, 67 insertions, 0 deletions
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index fae7e53382..5c36ff6764 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1778,7 +1778,9 @@ PHP_FUNCTION(socket_recvfrom) switch (php_sock->type) { case AF_UNIX: slen = sizeof(s_un); + memset(&s_un, 0, slen); s_un.sun_family = AF_UNIX; + retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&s_un, (socklen_t *)&slen); if (retval < 0) { diff --git a/ext/sockets/tests/bug76839.phpt b/ext/sockets/tests/bug76839.phpt new file mode 100644 index 0000000000..d63370cc31 --- /dev/null +++ b/ext/sockets/tests/bug76839.phpt @@ -0,0 +1,65 @@ +--TEST-- +Bug #76839: socket_recvfrom may return an invalid 'from' address on MacOS +--SKIPIF-- +<?php +if (strtolower(substr(PHP_OS, 0, 3)) === 'win') { + die('skip not valid for Windows.'); +} +if (!extension_loaded('sockets')) { + die('skip sockets extension not available.'); +} +--FILE-- +<?php + +// This bug only occurs when a specific portion of memory is unclean. +// Unforunately, looping around 10 times and using random paths is the +// best way I could manage to reproduce this problem without modifying php itself :-/ + +for ($i = 0; $i < 10; $i++) { + $senderSocketPath = '/tmp/' . substr(md5(rand()), 0, rand(8, 16)) . '.sock'; + $senderSocket = socket_create(AF_UNIX, SOCK_DGRAM, 0); + socket_bind($senderSocket, $senderSocketPath); + + $receiverSocketPath = '/tmp/' . substr(md5(rand()), 0, rand(8, 16)) . '.sock'; + $receiverSocket = socket_create(AF_UNIX, SOCK_DGRAM, 0); + socket_bind($receiverSocket, $receiverSocketPath); + + // Send message from sender socket to receiver socket + socket_sendto($senderSocket, 'Ping!', 5, 0, $receiverSocketPath); + + // Receive message on receiver socket + $from = ''; + $message = ''; + socket_recvfrom($receiverSocket, $message, 65535, 0, $from); + echo "Received '$message'\n"; + + // Respond to the sender using the 'from' address from socket_recvfrom + socket_sendto($receiverSocket, 'Pong!', 5, 0, $from); + echo "Responded to sender with 'Pong!'\n"; + + socket_close($receiverSocket); + unlink($receiverSocketPath); + socket_close($senderSocket); + unlink($senderSocketPath); +} +--EXPECT-- +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' +Received 'Ping!' +Responded to sender with 'Pong!' |