8000 Prevent buffer overrun while parsing an integer in a "query_int" value. · machack666/postgres@e11349f · GitHub
[go: up one dir, main page]

Skip to content

Commit e11349f

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 948a64d commit e11349f

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
@@ -55,24 +55,25 @@ typedef struct
5555
static int4
5656
gettoken(WORKSTATE * state, int4 *val)
5757
{
58-
char nnn[16],
59-
*curnnn;
58+
char nnn[16];
59+
int innn;
6060

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

63-
curnnn = nnn;
63+
innn = 0;
6464
while (1)
6565
{
66+
if (innn >= sizeof(nnn))
67+
return ERR; /* buffer overrun => syntax error */
6668
switch (state->state)
6769
{
6870
case WAITOPERAND:
69-
curnnn = nnn;
71+
innn = 0;
7072
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
7173
*(state->buf) == '-')
7274
{
7375
state->state = WAITENDOPERAND;
74-
*curnnn = *(state->buf);
75-
curnnn++;
76+
nnn[innn++] = *(state->buf);
7677
}
7778
else if (*(state->buf) == '!')
7879
{
@@ -92,13 +93,18 @@ gettoken(WORKSTATE * state, int4 *val)
9293
case WAITENDOPERAND:
9394
if (*(state->buf) >= '0' && *(state->buf) <= '9')
9495
{
95-
*curnnn = *(state->buf);
96-
curnnn++;
96+
nnn[innn++] = *(state->buf);
9797
}
9898
else
9999
{
100-
*curnnn = '\0';
101-
*val = (int4) atoi(nnn);
100+
long lval;
101+
102+
nnn[innn] = '\0';
103+
errno = 0;
104+
lval = strtol(nnn, NULL, 0);
105+
*val = (int4) lval;
106+
if (errno != 0 || (long) *val != lval)
107+
return ERR;
102108
state->state = WAITOPERATOR;
103109
return (state->count && *(state->buf) == '\0')
104110
? ERR : VAL;

0 commit comments

Comments
 (0)
0