fix: Guard against bulk length overflow

Clamp range in a couple library functions to values that can fit into an
iint, since we narrow it later.

A more comprehensive change that widens all of these values to 64 bits
will come in a future commit.
This commit is contained in:
michael-grunder
2026-06-01 10:02:54 -07:00
committed by Michael Grunder
parent 806b7b3f79
commit 7b2fdc6de1
2 changed files with 21 additions and 4 deletions
+20 -3
View File
@@ -778,6 +778,12 @@ redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes)
char *reply;
ssize_t got;
if (bytes < -1 || bytes > INT_MAX - 2) {
zend_throw_exception_ex(redis_exception_ce, 0,
"protocol error, invalid bulk length: %d", bytes);
return NULL;
}
if (-1 == bytes || -1 == redis_check_eof(redis_sock, 1, 0)) {
return NULL;
}
@@ -4642,18 +4648,29 @@ redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type,
}
PHP_REDIS_API int
redis_read_variant_bulk(RedisSock *redis_sock, int size, zval *z_ret
redis_read_variant_bulk(RedisSock *redis_sock, long size, zval *z_ret
)
{
int bytes;
if (size < -1 || size > INT_MAX - 2) {
zend_throw_exception_ex(redis_exception_ce, 0,
"protocol error, invalid bulk length: %ld", size);
ZVAL_FALSE(z_ret);
return -1;
}
bytes = size;
// Attempt to read the bulk reply
char *bulk_resp = redis_sock_read_bulk_reply(redis_sock, size);
char *bulk_resp = redis_sock_read_bulk_reply(redis_sock, bytes);
/* Set our reply to FALSE on failure, and the string on success */
if(bulk_resp == NULL) {
ZVAL_FALSE(z_ret);
return -1;
}
ZVAL_STRINGL(z_ret, bulk_resp, size);
ZVAL_STRINGL(z_ret, bulk_resp, bytes);
efree(bulk_resp);
return 0;
}
+1 -1
View File
@@ -238,7 +238,7 @@ PHP_REDIS_API int redis_acl_log_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *r
*/
PHP_REDIS_API int redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type, long *reply_info);
PHP_REDIS_API int redis_read_variant_bulk(RedisSock *redis_sock, int size, zval *z_ret);
PHP_REDIS_API int redis_read_variant_bulk(RedisSock *redis_sock, long size, zval *z_ret);
PHP_REDIS_API int redis_read_multibulk_recursive(RedisSock *redis_sock, long long elements, int status_strings, zval *z_ret);
PHP_REDIS_API int redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);