summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/sockets/sockets.c2
-rw-r--r--ext/sockets/tests/bug76839.phpt65
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!'