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
This commit is contained in:
Tom Lane 2011-01-27 17:42:00 -05:00
parent 948a64d2b9
commit e11349fdba

View File

@ -55,24 +55,25 @@ typedef struct
static int4
gettoken(WORKSTATE * state, int4 *val)
{
char nnn[16],
*curnnn;
char nnn[16];
int innn;
*val = 0; /* default result */
curnnn = nnn;
innn = 0;
while (1)
{
if (innn >= sizeof(nnn))
return ERR; /* buffer overrun => syntax error */
switch (state->state)
{
case WAITOPERAND:
curnnn = nnn;
innn = 0;
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
*(state->buf) == '-')
{
state->state = WAITENDOPERAND;
*curnnn = *(state->buf);
curnnn++;
nnn[innn++] = *(state->buf);
}
else if (*(state->buf) == '!')
{
@ -92,13 +93,18 @@ gettoken(WORKSTATE * state, int4 *val)
case WAITENDOPERAND:
if (*(state->buf) >= '0' && *(state->buf) <= '9')
{
*curnnn = *(state->buf);
curnnn++;
nnn[innn++] = *(state->buf);
}
else
{
*curnnn = '\0';
*val = (int4) atoi(nnn);
long lval;
nnn[innn] = '\0';
errno = 0;
lval = strtol(nnn, NULL, 0);
*val = (int4) lval;
if (errno != 0 || (long) *val != lval)
return ERR;
state->state = WAITOPERATOR;
return (state->count && *(state->buf) == '\0')
? ERR : VAL;