Skip to content

Commit 46213f8

Browse files
authored
ext/sockets: socket_addrinfo_lookup narrowing down socket family check to AF_INET/AF_INET6 only. (#19040)
1 parent a64cdd6 commit 46213f8

File tree

2 files changed

+17
-55
lines changed

2 files changed

+17
-55
lines changed

ext/sockets/sockets.c

Lines changed: 16 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,8 +2774,16 @@ PHP_FUNCTION(socket_addrinfo_lookup)
27742774
zend_argument_type_error(3, "\"ai_family\" key must be of type int, %s given", zend_zval_type_name(hint));
27752775
RETURN_THROWS();
27762776
}
2777-
if (val < 0 || val >= AF_MAX) {
2778-
zend_argument_value_error(3, "\"ai_family\" key must be between 0 and %d", AF_MAX - 1);
2777+
// Some platforms support also PF_LOCAL/AF_UNIX (e.g. FreeBSD) but the security concerns implied
2778+
// make it not worth handling it (e.g. unwarranted write permissions on the socket).
2779+
// Note existing socket_addrinfo* api already forbid such case.
2780+
#ifdef HAVE_IPV6
2781+
if (val != AF_INET && val != AF_INET6) {
2782+
zend_argument_value_error(3, "\"ai_family\" key must be AF_INET or AF_INET6");
2783+
#else
2784+
if (val != AF_INET) {
2785+
zend_argument_value_error(3, "\"ai_family\" key must be AF_INET");
2786+
#endif
27792787
RETURN_THROWS();
27802788
}
27812789
hints.ai_family = (int)val;
@@ -2827,7 +2835,6 @@ PHP_FUNCTION(socket_addrinfo_lookup)
28272835
PHP_FUNCTION(socket_addrinfo_bind)
28282836
{
28292837
zval *arg1;
2830-
int retval;
28312838
php_addrinfo *ai;
28322839
php_socket *php_sock;
28332840

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

28382845
ai = Z_ADDRESS_INFO_P(arg1);
28392846

2847+
ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6);
2848+
28402849
PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family);
28412850

28422851
object_init_ex(return_value, socket_ce);
@@ -2855,31 +2864,7 @@ PHP_FUNCTION(socket_addrinfo_bind)
28552864
php_sock->error = 0;
28562865
php_sock->blocking = 1;
28572866

2858-
switch(php_sock->type) {
2859-
case AF_UNIX:
2860-
{
2861-
// AF_UNIX sockets via getaddrino are not implemented due to security problems
2862-
close(php_sock->bsd_socket);
2863-
zval_ptr_dtor(return_value);
2864-
RETURN_FALSE;
2865-
}
2866-
2867-
case AF_INET:
2868-
#ifdef HAVE_IPV6
2869-
case AF_INET6:
2870-
#endif
2871-
{
2872-
retval = bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen);
2873-
break;
2874-
}
2875-
default:
2876-
close(php_sock->bsd_socket);
2877-
zval_ptr_dtor(return_value);
2878-
zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6");
2879-
RETURN_THROWS();
2880-
}
2881-
2882-
if (retval != 0) {
2867+
if (bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) {
28832868
PHP_SOCKET_ERROR(php_sock, "Unable to bind address", errno);
28842869
close(php_sock->bsd_socket);
28852870
zval_ptr_dtor(return_value);
@@ -2892,7 +2877,6 @@ PHP_FUNCTION(socket_addrinfo_bind)
28922877
PHP_FUNCTION(socket_addrinfo_connect)
28932878
{
28942879
zval *arg1;
2895-
int retval;
28962880
php_addrinfo *ai;
28972881
php_socket *php_sock;
28982882

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

29032887
ai = Z_ADDRESS_INFO_P(arg1);
29042888

2889+
ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6);
2890+
29052891
PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family);
29062892

29072893
object_init_ex(return_value, socket_ce);
@@ -2920,31 +2906,7 @@ PHP_FUNCTION(socket_addrinfo_connect)
29202906
php_sock->error = 0;
29212907
php_sock->blocking = 1;
29222908

2923-
switch(php_sock->type) {
2924-
case AF_UNIX:
2925-
{
2926-
// AF_UNIX sockets via getaddrino are not implemented due to security problems
2927-
close(php_sock->bsd_socket);
2928-
zval_ptr_dtor(return_value);
2929-
RETURN_FALSE;
2930-
}
2931-
2932-
case AF_INET:
2933-
#ifdef HAVE_IPV6
2934-
case AF_INET6:
2935-
#endif
2936-
{
2937-
retval = connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen);
2938-
break;
2939-
}
2940-
default:
2941-
zend_argument_value_error(1, "socket type must be one of AF_UNIX, AF_INET, or AF_INET6");
2942-
close(php_sock->bsd_socket);
2943-
zval_ptr_dtor(return_value);
2944-
RETURN_THROWS();
2945-
}
2946-
2947-
if (retval != 0) {
2909+
if (connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) {
29482910
PHP_SOCKET_ERROR(php_sock, "Unable to connect address", errno);
29492911
close(php_sock->bsd_socket);
29502912
zval_ptr_dtor(return_value);

ext/sockets/tests/socket_getaddrinfo_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type i
110110
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given
111111
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given
112112
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given
113-
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be between 0 and %d
113+
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be AF_INET%A
114114
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be between 0 and %d
115115
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be between 0 and %d
116116
socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be between 0 and %d

0 commit comments

Comments
 (0)