Skip to content

Commit 009a0c2

Browse files
committed
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 3e9b530, which replaced the original bounded strlcpy with an unguarded memcpy. Restore the strlcpy plus else-if guard, matching PHP-8.4. Closes GH-22379
1 parent 3154731 commit 009a0c2

1 file changed

Lines changed: 3 additions & 4 deletions

File tree

ext/sockets/conversions.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,11 +1270,10 @@ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context
12701270
#elif defined(SIOCGIFINDEX)
12711271
{
12721272
struct ifreq ifr;
1273-
if (ZSTR_LEN(str) >= sizeof(ifr.ifr_name)) {
1273+
if (strlcpy(ifr.ifr_name, ZSTR_VAL(str), sizeof(ifr.ifr_name))
1274+
>= sizeof(ifr.ifr_name)) {
12741275
do_from_zval_err(ctx, "the interface name \"%s\" is too large ", ZSTR_VAL(str));
1275-
}
1276-
memcpy(ifr.ifr_name, ZSTR_VAL(str), ZSTR_LEN(str) + 1);
1277-
if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) {
1276+
} else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) {
12781277
if (errno == ENODEV) {
12791278
do_from_zval_err(ctx, "no interface with name \"%s\" could be "
12801279
"found", ZSTR_VAL(str));

0 commit comments

Comments
 (0)