Skip to content

ext/sockets: socket_addrinfo_lookup narrowing down socket family check. #19040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 16 additions & 54 deletions ext/sockets/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -2774,8 +2774,16 @@ PHP_FUNCTION(socket_addrinfo_lookup)
zend_argument_type_error(3, "\"ai_family\" key must be of type int, %s given", zend_zval_type_name(hint));
RETURN_THROWS();
}
if (val < 0 || val >= AF_MAX) {
zend_argument_value_error(3, "\"ai_family\" key must be between 0 and %d", AF_MAX - 1);
// Some platforms support also PF_LOCAL/AF_UNIX (e.g. FreeBSD) but the security concerns implied
// make it not worth handling it (e.g. unwarranted write permissions on the socket).
// Note existing socket_addrinfo* api already forbid such case.
#ifdef HAVE_IPV6
if (val != AF_INET && val != AF_INET6) {
zend_argument_value_error(3, "\"ai_family\" key must be AF_INET or AF_INET6");
#else
if (val != AF_INET) {
zend_argument_value_error(3, "\"ai_family\" key must be AF_INET");
#endif
RETURN_THROWS();
}
hints.ai_family = (int)val;
Expand Down Expand Up @@ -2827,7 +2835,6 @@ PHP_FUNCTION(socket_addrinfo_lookup)
PHP_FUNCTION(socket_addrinfo_bind)
{
zval *arg1;
int retval;
php_addrinfo *ai;
php_socket *php_sock;

Expand All @@ -2837,6 +2844,8 @@ PHP_FUNCTION(socket_addrinfo_bind)

ai = Z_ADDRESS_INFO_P(arg1);

ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6);

PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family);

object_init_ex(return_value, socket_ce);
Expand All @@ -2855,31 +2864,7 @@ PHP_FUNCTION(socket_addrinfo_bind)
php_sock->error = 0;
php_sock->blocking = 1;

switch(php_sock->type) {
case AF_UNIX:
{
// AF_UNIX sockets via getaddrino are not implemented due to security problems
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
RETURN_FALSE;
}

case AF_INET:
#ifdef HAVE_IPV6
case AF_INET6:
#endif
{
retval = bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen);
break;
}
default:
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6");
RETURN_THROWS();
}

if (retval != 0) {
if (bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) {
PHP_SOCKET_ERROR(php_sock, "Unable to bind address", errno);
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
Expand All @@ -2892,7 +2877,6 @@ PHP_FUNCTION(socket_addrinfo_bind)
PHP_FUNCTION(socket_addrinfo_connect)
{
zval *arg1;
int retval;
php_addrinfo *ai;
php_socket *php_sock;

Expand All @@ -2902,6 +2886,8 @@ PHP_FUNCTION(socket_addrinfo_connect)

ai = Z_ADDRESS_INFO_P(arg1);

ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6);

PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family);

object_init_ex(return_value, socket_ce);
Expand All @@ -2920,31 +2906,7 @@ PHP_FUNCTION(socket_addrinfo_connect)
php_sock->error = 0;
php_sock->blocking = 1;

switch(php_sock->type) {
case AF_UNIX:
{
// AF_UNIX sockets via getaddrino are not implemented due to security problems
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
RETURN_FALSE;
}

case AF_INET:
#ifdef HAVE_IPV6
case AF_INET6:
#endif
{
retval = connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen);
break;
}
default:
zend_argument_value_error(1, "socket type must be one of AF_UNIX, AF_INET, or AF_INET6");
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
RETURN_THROWS();
}

if (retval != 0) {
if (connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) {
PHP_SOCKET_ERROR(php_sock, "Unable to connect address", errno);
close(php_sock->bsd_socket);
zval_ptr_dtor(return_value);
Expand Down
2 changes: 1 addition & 1 deletion ext/sockets/tests/socket_getaddrinfo_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type i
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be between 0 and %d
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be AF_INET%A
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be between 0 and %d
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be between 0 and %d
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be between 0 and %d
Expand Down