From ccc84010d09acbd8c0fb727f5b2f828bc48edf95 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 6 Dec 2025 10:13:18 +0000 Subject: [PATCH] ext/sockets: socket_addrinfo_lookup() allows AF_UNSPEC for ai_family. while still filtering out IPC like addresses and so on. --- ext/sockets/sockets.c | 18 ++++++++++++------ ext/sockets/sockets.stub.php | 7 +++++++ ext/sockets/sockets_arginfo.h | 5 ++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 4a9332498c3cc..e352d18d70571 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2802,14 +2802,16 @@ PHP_FUNCTION(socket_addrinfo_lookup) // 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. + if (val != AF_UNSPEC) { #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"); + 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"); + if (val != AF_INET) { + zend_argument_value_error(3, "\"ai_family\" key must be AF_INET"); #endif - RETURN_THROWS(); + RETURN_THROWS(); + } } hints.ai_family = (int)val; } else { @@ -2833,7 +2835,11 @@ PHP_FUNCTION(socket_addrinfo_lookup) zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); for (rp = result; rp != NULL; rp = rp->ai_next) { - if (rp->ai_family != AF_UNSPEC) { + if (rp->ai_family == AF_INET +#ifdef HAVE_IPV6 + || rp->ai_family != AF_INET6 +#endif + ) { zval zaddr; object_init_ex(&zaddr, address_info_ce); diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 3df9b598a1e8f..045b239b46a1e 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -19,6 +19,13 @@ */ const AF_INET6 = UNKNOWN; #endif +#ifdef AF_UNSPEC +/** + * @var int + * @cvalue AF_UNSPEC + */ +const AF_UNSPEC = UNKNOWN; +#endif #ifdef AF_DIVERT /** * @var int diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index edfc344ff8cc0..ce20de9f61df3 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f754368e28f6e45bf3a63a403e49f5659c29d2c6 */ + * Stub hash: 66fae9539bdaa50d736dbfa53c41f2f0059c88c6 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -317,6 +317,9 @@ static void register_sockets_symbols(int module_number) #if defined(HAVE_IPV6) REGISTER_LONG_CONSTANT("AF_INET6", AF_INET6, CONST_PERSISTENT); #endif +#if defined(AF_UNSPEC) + REGISTER_LONG_CONSTANT("AF_UNSPEC", AF_UNSPEC, CONST_PERSISTENT); +#endif #if defined(AF_DIVERT) REGISTER_LONG_CONSTANT("AF_DIVERT", AF_DIVERT, CONST_PERSISTENT); #endif