Skip to content

Commit d6d1456

Browse files
committed
Prevent buffer overrun while parsing an integer in a "query_int" value.
contrib/intarray's gettoken() uses a fixed-size buffer to collect an integer's digits, and did not guard against overrunning the buffer. This is at least a backend crash risk, and in principle might allow arbitrary code execution. The code didn't check for overflow of the integer value either, which while not presenting a crash risk was still bad. Thanks to Apple Inc's security team for reporting this issue and supplying the fix. Security: CVE-2010-4015
1 parent 67dbe72 commit d6d1456

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

contrib/intarray/_int_bool.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,25 @@ typedef struct
6262
static int4
6363
gettoken(WORKSTATE *state, int4 *val)
6464
{
65-
char nnn[16],
66-
*curnnn;
65+
char nnn[16];
66+
int innn;
6767

6868
*val = 0; /* default result */
6969

70-
curnnn = nnn;
70+
innn = 0;
7171
while (1)
7272
{
73+
if (innn >= sizeof(nnn))
74+
return ERR; /* buffer overrun => syntax error */
7375
switch (state->state)
7476
{
7577
case WAITOPERAND:
76-
curnnn = nnn;
78+
innn = 0;
7779
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
7880
*(state->buf) == '-')
7981
{
8082
state->state = WAITENDOPERAND;
81-
*curnnn = *(state->buf);
82-
curnnn++;
83+
nnn[innn++] = *(state->buf);
8384
}
8485
else if (*(state->buf) == '!')
8586
{
@@ -99,13 +100,18 @@ gettoken(WORKSTATE *state, int4 *val)
99100
case WAITENDOPERAND:
100101
if (*(state->buf) >= '0' && *(state->buf) <= '9')
101102
{
102-
*curnnn = *(state->buf);
103-
curnnn++;
103+
nnn[innn++] = *(state->buf);
104104
}
105105
else
106106
{
107-
*curnnn = '\0';
108-
*val = (int4) atoi(nnn);
107+
long lval;
108+
109+
nnn[innn] = '\0';
110+
errno = 0;
111+
lval = strtol(nnn, NULL, 0);
112+
*val = (int4) lval;
113+
if (errno != 0 || (long) *val != lval)
114+
return ERR;
109115
state->state = WAITOPERATOR;
110116
return (state->count && *(state->buf) == '\0')
111117
? ERR : VAL;

0 commit comments

Comments
 (0)