Skip to content

Commit

Permalink
ext/sockets: socket_create_listen() check port value beforehand.
Browse files Browse the repository at this point in the history
port is a 16 bit field, limited to the 65535 value then.
Note that 0 is a valid case for ephemeral port.

close GH-17281
  • Loading branch information
devnexen committed Dec 27, 2024
1 parent 2b36680 commit 00fe9b2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ PHP NEWS
with timeout setting on windows. (David Carlier)
. Added TCP_FUNCTION_ALIAS, TCP_REUSPORT_LB_NUMA, TCP_REUSPORT_LB_NUMA_NODOM,
TCP_REUSPORT_LB_CURDOM, TCP_BBR_ALGORITHM constants.
. socket_create_listen() throws an exception on invalid port value.
(David Carlier)

- Standard:
. Fixed crypt() tests on musl when using --with-external-libcrypt
Expand Down
4 changes: 4 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ PHP 8.5 UPGRADE NOTES
. posix_fpathconf checks invalid file descriptors and sets
last_error to EBADF and raises an E_WARNING message.

- Sockets:
. socket_create_listen throws a ValueError if the port is
lower than 0 or greater than 65535.

- Zlib:
. The "use_include_path" argument for the
gzfile, gzopen and readgzfile functions had been changed
Expand Down
11 changes: 8 additions & 3 deletions ext/sockets/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ zend_module_entry sockets_module_entry = {
ZEND_GET_MODULE(sockets)
#endif

static bool php_open_listen_sock(php_socket *sock, int port, int backlog) /* {{{ */
static bool php_open_listen_sock(php_socket *sock, unsigned short port, int backlog) /* {{{ */
{
struct sockaddr_in la = {0};
struct hostent *hp;
Expand All @@ -232,7 +232,7 @@ static bool php_open_listen_sock(php_socket *sock, int port, int backlog) /* {{{

memcpy((char *) &la.sin_addr, hp->h_addr, hp->h_length);
la.sin_family = hp->h_addrtype;
la.sin_port = htons((unsigned short) port);
la.sin_port = htons(port);

sock->bsd_socket = socket(PF_INET, SOCK_STREAM, 0);
sock->blocking = 1;
Expand Down Expand Up @@ -680,10 +680,15 @@ PHP_FUNCTION(socket_create_listen)
Z_PARAM_LONG(backlog)
ZEND_PARSE_PARAMETERS_END();

if (port < 0 || port > USHRT_MAX) {
zend_argument_value_error(1, "must be between 0 and %u", USHRT_MAX);
RETURN_THROWS();
}

object_init_ex(return_value, socket_ce);
php_sock = Z_SOCKET_P(return_value);

if (!php_open_listen_sock(php_sock, port, backlog)) {
if (!php_open_listen_sock(php_sock, (unsigned short)port, backlog)) {
zval_ptr_dtor(return_value);
RETURN_FALSE;
}
Expand Down
24 changes: 24 additions & 0 deletions ext/sockets/tests/socket_create_listen_invalid_port.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
socket_create_listen() using invalid ports
--EXTENSIONS--
sockets
--FILE--
<?php
var_dump(socket_create_listen(0));

try {
socket_create_listen(-1);
} catch (\ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
try {
socket_create_listen(65536);
} catch (\ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
?>
--EXPECT--
object(Socket)#1 (0) {
}
socket_create_listen(): Argument #1 ($port) must be between 0 and 65535
socket_create_listen(): Argument #1 ($port) must be between 0 and 65535

0 comments on commit 00fe9b2

Please sign in to comment.