Skip to content

Commit 754ea6e

Browse files
committed
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
1 parent c1773a1 commit 754ea6e

4 files changed

Lines changed: 12 additions & 4 deletions

File tree

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ PHP NEWS
55
- Date:
66
. Fixed leak on double DatePeriod::__construct() call. (ilutov)
77

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

1013
- Calendar:

ext/sockets/conversions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,7 @@ static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
12061206
if (iovlen > UINT_MAX) {
12071207
do_to_zval_err(ctx, "unexpectedly large value for iov_len: %lu",
12081208
(unsigned long)iovlen);
1209+
return;
12091210
}
12101211
array_init_size(zv, (uint32_t)iovlen);
12111212

ext/sockets/multicast.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ zend_result php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struc
635635
retry:
636636
retval = GetIpAddrTable(addr_table, &size, 0);
637637
if (retval == ERROR_INSUFFICIENT_BUFFER) {
638-
erealloc(addr_table, size);
638+
addr_table = erealloc(addr_table, size);
639639
goto retry;
640640
}
641641
if (retval != NO_ERROR) {
@@ -677,7 +677,7 @@ zend_result php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, uns
677677
retry:
678678
retval = GetIpAddrTable(addr_table, &size, 0);
679679
if (retval == ERROR_INSUFFICIENT_BUFFER) {
680-
erealloc(addr_table, size);
680+
addr_table = erealloc(addr_table, size);
681681
goto retry;
682682
}
683683
if (retval != NO_ERROR) {

ext/sockets/sockets.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ PHP_FUNCTION(socket_get_option)
18391839
#endif
18401840

18411841
optlen = sizeof(other_val);
1842+
other_val = 0;
18421843

18431844
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
18441845
PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno);
@@ -1864,6 +1865,10 @@ PHP_FUNCTION(socket_set_option)
18641865
int timeout;
18651866
#else
18661867
struct timeval tv;
1868+
#endif
1869+
#ifdef SO_ATTACH_REUSEPORT_CBPF
1870+
struct sock_filter cbpf[8] = {0};
1871+
struct sock_fprog bpfprog;
18671872
#endif
18681873
zend_long level, optname;
18691874
void *opt_ptr;
@@ -2074,8 +2079,6 @@ PHP_FUNCTION(socket_set_option)
20742079
optname = SO_DETACH_BPF;
20752080
} else {
20762081
uint32_t k = (uint32_t)cbpf_val;
2077-
static struct sock_filter cbpf[8] = {0};
2078-
static struct sock_fprog bpfprog;
20792082

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

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

0 commit comments

Comments
 (0)