From 08c0e82e76cc4399d968aeb58e2b4f80e93cdfb1 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sat, 20 Jun 2026 21:09:19 -0400 Subject: [PATCH] ext/sockets: bound interface name copy in from_zval_write_ifindex() The SIOCGIFINDEX fallback checked ZSTR_LEN against sizeof(ifr.ifr_name) but did not return on overflow, then memcpy'd ZSTR_LEN+1 bytes into the fixed ifr_name buffer, so an over-long interface name overran the stack. This regressed in 3e9b530d625, which replaced the original bounded strlcpy with an unguarded memcpy. Restore the strlcpy plus else-if guard, matching PHP-8.4 and PHP-8.5. --- ext/sockets/conversions.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 76a08559b809..abf9004f522d 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1281,11 +1281,10 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context #elif defined(SIOCGIFINDEX) { struct ifreq ifr; - if (ZSTR_LEN(str) >= sizeof(ifr.ifr_name)) { + if (strlcpy(ifr.ifr_name, ZSTR_VAL(str), sizeof(ifr.ifr_name)) + >= sizeof(ifr.ifr_name)) { do_from_zval_err(ctx, "the interface name \"%s\" is too large ", ZSTR_VAL(str)); - } - memcpy(ifr.ifr_name, ZSTR_VAL(str), ZSTR_LEN(str) + 1); - if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) { + } else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) { if (errno == ENODEV) { do_from_zval_err(ctx, "no interface with name \"%s\" could be " "found", ZSTR_VAL(str));