[php-src] master: ext/sockets: bound interface name copy in from_zval_write_ifindex()
Ilia Alshanetsky <[email protected]> Fri, 17 Jul 2026 19:31:57 +0000
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Date: 2026-07-17T15:25:19-04:00
Commit: https://github.com/php/php-src/commit/009a0c276d32b214166d72dc73634b8623c580f1
Raw diff: https://github.com/php/php-src/commit/009a0c276d32b214166d72dc73634b8623c580f1.diff
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.
Closes GH-22379
Changed paths:
M ext/sockets/conversions.c
Diff:
diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c
index d6f208d69868..61a76fb4893e 100644
--- a/ext/sockets/conversions.c
+++ b/ext/sockets/conversions.c
@@ -1270,11 +1270,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));