Commit 754ea6e14e6 for php.net

commit 754ea6e14e60ea36d2d5f4e5dd4c404f3ecfeb25
Author: David Carlier <devnexen@gmail.com>
Date:   Fri Jul 17 20:06:41 2026 +0100

    ext/sockets: memory related issues fix.

    - php_if_index_to_addr4()/php_add4_to_if_index() use-after-free on the Windows address table.

    GetIpAddrTable() was retried against addr_table after an erealloc() whose
    return value was discarded, so on ERROR_INSUFFICIENT_BUFFER it wrote into
    the freed block. Assign the reallocated pointer back before retrying.

    - socket_import_stream() double-close of the stream descriptor on error.

    socket_import_file_descriptor() sets bsd_socket before zstream is copied,
    so a failing import freed the object with zstream still UNDEF and closed
    the fd still owned by the stream. Invalidate bsd_socket on the error path.

    - socket_set_option() data race on the reuseport CBPF filter buffers.

    The cbpf/bpfprog buffers were function-local statics shared across threads,
    so concurrent SO_ATTACH_REUSEPORT_CBPF calls could install a torn filter.
    Move them to function scope so they outlive the block up to setsockopt()
    without being shared.

    - socket_get_option() leaks uninitialized bytes for sub-int options.

    The generic path only corrected 1-byte options; an option returning 0/2/3
    bytes left the high bytes of other_val uninitialized before RETURN_LONG.
    Zero-initialize it before getsockopt().

    - to_zval_read_iov() missing bail out on oversized iov_len.

    The error was recorded but execution fell through to array_init_size() and
    the loop with a truncated length. Return right after reporting it.

    close GH-22794

diff --git a/NEWS b/NEWS
index 8a94a173afd..ccae29155db 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ PHP                                                                        NEWS
 - Date:
   . Fixed leak on double DatePeriod::__construct() call. (ilutov)

+- Sockets:
+  . Fixed various memory related issues in ext/sockets. (David Carlier)
+
 30 Jul 2026, PHP 8.4.24

 - Calendar:
diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c
index eb4e58b3988..867723f42de 100644
--- a/ext/sockets/conversions.c
+++ b/ext/sockets/conversions.c
@@ -1206,6 +1206,7 @@ static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
 	if (iovlen > UINT_MAX) {
 		do_to_zval_err(ctx, "unexpectedly large value for iov_len: %lu",
 				(unsigned long)iovlen);
+		return;
 	}
 	array_init_size(zv, (uint32_t)iovlen);

diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c
index e258ca3e66e..50808ef5b3a 100644
--- a/ext/sockets/multicast.c
+++ b/ext/sockets/multicast.c
@@ -635,7 +635,7 @@ zend_result php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struc
 retry:
 	retval = GetIpAddrTable(addr_table, &size, 0);
 	if (retval == ERROR_INSUFFICIENT_BUFFER) {
-		erealloc(addr_table, size);
+		addr_table = erealloc(addr_table, size);
 		goto retry;
 	}
 	if (retval != NO_ERROR) {
@@ -677,7 +677,7 @@ zend_result php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, uns
 retry:
 	retval = GetIpAddrTable(addr_table, &size, 0);
 	if (retval == ERROR_INSUFFICIENT_BUFFER) {
-		erealloc(addr_table, size);
+		addr_table = erealloc(addr_table, size);
 		goto retry;
 	}
 	if (retval != NO_ERROR) {
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index 79d5f77856d..565a2d791bc 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -1839,6 +1839,7 @@ PHP_FUNCTION(socket_get_option)
 #endif

 	optlen = sizeof(other_val);
+	other_val = 0;

 	if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
 		PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno);
@@ -1864,6 +1865,10 @@ PHP_FUNCTION(socket_set_option)
 	int						timeout;
 #else
 	struct					timeval tv;
+#endif
+#ifdef SO_ATTACH_REUSEPORT_CBPF
+	struct sock_filter cbpf[8] = {0};
+	struct sock_fprog bpfprog;
 #endif
 	zend_long					level, optname;
 	void 					*opt_ptr;
@@ -2074,8 +2079,6 @@ PHP_FUNCTION(socket_set_option)
 				optname = SO_DETACH_BPF;
 			} else {
 				uint32_t k = (uint32_t)cbpf_val;
-				static struct sock_filter cbpf[8] = {0};
-				static struct sock_fprog bpfprog;

 				switch (k) {
 					case SKF_AD_CPU:
@@ -2357,6 +2360,7 @@ PHP_FUNCTION(socket_import_stream)
 	retsock = Z_SOCKET_P(return_value);

 	if (!socket_import_file_descriptor(socket, retsock)) {
+		retsock->bsd_socket = -1;
 		zval_ptr_dtor(return_value);
 		RETURN_FALSE;
 	}