Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5c6e2d2

Browse files
iliaalmichael-grunder
authored andcommitted
library: replace atol with bounded strtoll for RESP length parsing
atol returns undefined behavior on overflow per C11 7.22.1.4. glibc saturates to LONG_MAX, but musl, BSD libc, and Windows libc differ. Replace atol / atoi at the three RESP length parse sites in library.c with strtoll plus ERANGE rejection. The wire input is server- controlled; an out-of-range value should drop the reply rather than land an implementation-defined value in downstream length arithmetic.
1 parent b112875 commit 5c6e2d2

1 file changed

Lines changed: 33 additions & 3 deletions

File tree

library.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "common.h"
88
#include "php_network.h"
99
#include <sys/types.h>
10+
#include <errno.h>
11+
#include <limits.h>
1012

1113
#ifdef HAVE_REDIS_IGBINARY
1214
#include "igbinary/igbinary.h"
@@ -364,7 +366,17 @@ read_mbulk_header(RedisSock *redis_sock, int *nelem)
364366
return FAILURE;
365367
}
366368

367-
*nelem = atoi(line + 1);
369+
{
370+
char *endptr;
371+
long long n;
372+
373+
errno = 0;
374+
n = strtoll(line + 1, &endptr, 10);
375+
if (endptr == line + 1 || errno == ERANGE || n < -1 || n > INT_MAX) {
376+
return FAILURE;
377+
}
378+
*nelem = (int)n;
379+
}
368380

369381
return SUCCESS;
370382
}
@@ -822,7 +834,17 @@ redis_sock_read(RedisSock *redis_sock, int *buf_len)
822834

823835
return NULL;
824836
case '$':
825-
*buf_len = atoi(inbuf + 1);
837+
{
838+
char *endptr;
839+
long long n;
840+
841+
errno = 0;
842+
n = strtoll(inbuf + 1, &endptr, 10);
843+
if (endptr == inbuf + 1 || errno == ERANGE || n < -1 || n > INT_MAX) {
844+
return NULL;
845+
}
846+
*buf_len = (int)n;
847+
}
826848
return redis_sock_read_bulk_reply(redis_sock, *buf_len);
827849

828850
case '*':
@@ -4567,7 +4589,15 @@ redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type,
45674589
}
45684590

45694591
/* Set our size response */
4570-
*reply_info = atol(inbuf);
4592+
{
4593+
char *endptr;
4594+
4595+
errno = 0;
4596+
*reply_info = strtol(inbuf, &endptr, 10);
4597+
if (endptr == inbuf || errno == ERANGE) {
4598+
return -1;
4599+
}
4600+
}
45714601
} else {
45724602
/* Always initialize to prevent UB */
45734603
*reply_info = 0;

0 commit comments

Comments
 (0)