Skip to content

Commit 4b24f5d

Browse files
committed
Merge branch 'PHP-8.3'
2 parents 8fd1388 + 784b745 commit 4b24f5d

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

ext/standard/tests/streams/bug60106.phpt renamed to ext/standard/tests/streams/bug60106-001.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Bug#60106 (stream_socket_server silently truncates long unix socket paths)
2+
Bug #60106 (stream_socket_server silently truncates long unix socket paths)
33
--SKIPIF--
44
<?php
55
if( substr(PHP_OS, 0, 3) == "WIN" )
@@ -11,9 +11,9 @@ error_reporting(E_ALL | E_NOTICE);
1111
$socket_file = "/tmp/" . str_repeat("a", 512);
1212
function get_truncated_socket_filename($errno, $errmsg, $file, $line) {
1313
global $socket_file;
14-
print_r ($errmsg);
14+
echo $errmsg, "\n";
1515
preg_match("#maximum allowed length of (\d+) bytes#", $errmsg, $matches);
16-
$socket_file = substr($socket_file, 0, intval($matches[1]) - 1);
16+
$socket_file = substr($socket_file, 0, intval($matches[1]));
1717
}
1818
set_error_handler("get_truncated_socket_filename", E_NOTICE);
1919
stream_socket_server("unix://" . $socket_file);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Bug #60106 (stream_socket_server with abstract unix socket paths)
3+
--SKIPIF--
4+
<?php
5+
if (PHP_OS != "Linux") die("skip Only for Linux systems");
6+
?>
7+
--FILE--
8+
<?php
9+
error_reporting(E_ALL | E_NOTICE);
10+
11+
/* This figures out the max length for normal sockets */
12+
$socket_file = "/tmp/" . str_repeat("a", 512);
13+
function get_truncated_socket_filename($errno, $errmsg, $file, $line) {
14+
global $socket_file, $max_normal_length;
15+
echo $errmsg, "\n";
16+
preg_match("#maximum allowed length of (\d+) bytes#", $errmsg, $matches);
17+
$max_normal_length = intval($matches[1]);
18+
$socket_file = substr($socket_file, 0, $max_normal_length);
19+
}
20+
set_error_handler("get_truncated_socket_filename", E_NOTICE);
21+
22+
stream_socket_server("unix://" . $socket_file);
23+
unlink($socket_file);
24+
25+
/* No we create an abstract one, prefixed with \0 so this should now work */
26+
$abstract_socket = "\0" . $socket_file;
27+
stream_socket_server("unix://" . $abstract_socket);
28+
29+
$old_max_length = $max_normal_length;
30+
31+
/* And now one longer, which should fail again */
32+
$abstract_socket_long = "\0" . $abstract_socket . 'X';
33+
stream_socket_server("unix://" . $abstract_socket_long);
34+
35+
echo "Allowed length is now one more: ", $max_normal_length == $old_max_length + 1 ? "yes" : "no", "\n";
36+
?>
37+
--EXPECTF--
38+
stream_socket_server(): socket path exceeded the maximum allowed length of %d bytes and was truncated
39+
stream_socket_server(): socket path exceeded the maximum allowed length of %d bytes and was truncated
40+
Allowed length is now one more: yes

main/streams/xp_socket.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,18 +590,23 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock
590590
memset(unix_addr, 0, sizeof(*unix_addr));
591591
unix_addr->sun_family = AF_UNIX;
592592

593+
/* Abstract namespace does not need to be NUL-terminated, while path-based
594+
* sockets should be. */
595+
bool is_abstract_ns = xparam->inputs.namelen > 0 && xparam->inputs.name[0] == '\0';
596+
unsigned long max_length = is_abstract_ns ? sizeof(unix_addr->sun_path) : sizeof(unix_addr->sun_path) - 1;
597+
593598
/* we need to be binary safe on systems that support an abstract
594599
* namespace */
595-
if (xparam->inputs.namelen >= sizeof(unix_addr->sun_path)) {
600+
if (xparam->inputs.namelen > max_length) {
596601
/* On linux, when the path begins with a NUL byte we are
597602
* referring to an abstract namespace. In theory we should
598603
* allow an extra byte below, since we don't need the NULL.
599604
* BUT, to get into this branch of code, the name is too long,
600605
* so we don't care. */
601-
xparam->inputs.namelen = sizeof(unix_addr->sun_path) - 1;
606+
xparam->inputs.namelen = max_length;
602607
php_error_docref(NULL, E_NOTICE,
603608
"socket path exceeded the maximum allowed length of %lu bytes "
604-
"and was truncated", (unsigned long)sizeof(unix_addr->sun_path));
609+
"and was truncated", max_length);
605610
}
606611

607612
memcpy(unix_addr->sun_path, xparam->inputs.name, xparam->inputs.namelen);

0 commit comments

Comments
 (0)