Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7ccb6dc

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 0ac8c8d commit 7ccb6dc

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

contrib/intarray/_int_bool.c

+16-10
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,25 @@ typedef struct
5656
static int4
5757
gettoken(WORKSTATE *state, int4 *val)
5858
{
59-
char nnn[16],
60-
*curnnn;
59+
char nnn[16];
60+
int innn;
6161

6262
*val = 0; /* default result */
6363

64-
curnnn = nnn;
64+
innn = 0;
6565
while (1)
6666
{
67+
if (innn >= sizeof(nnn))
68+
return ERR; /* buffer overrun => syntax error */
6769
switch (state->state)
6870
{
6971
case WAITOPERAND:
70-
curnnn = nnn;
72+
innn = 0;
7173
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
7274
*(state->buf) == '-')
7375
{
7476
state->state = WAITENDOPERAND;
75-
*curnnn = *(state->buf);
76-
curnnn++;
77+
nnn[innn++] = *(state->buf);
7778
}
7879
else if (*(state->buf) == '!')
7980
{
@@ -93,13 +94,18 @@ gettoken(WORKSTATE *state, int4 *val)
9394
case WAITENDOPERAND:
9495
if (*(state->buf) >= '0' && *(state->buf) <= '9')
9596
{
96-
*curnnn = *(state->buf);
97-
curnnn++;
97+
nnn[innn++] = *(state->buf);
9898
}
9999
else
100100
{
101-
*curnnn = '\0';
102-
*val = (int4) atoi(nnn);
101+
long lval;
102+
103+
nnn[innn] = '\0';
104+
errno = 0;
105+
lval = strtol(nnn, NULL, 0);
106+
*val = (int4) lval;
107+
if (errno != 0 || (long) *val != lval)
108+
return ERR;
103109
state->state = WAITOPERATOR;
104110
return (state->count && *(state->buf) == '\0')
105111
? ERR : VAL;

0 commit comments

Comments
 (0)