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:
parent
0ac8c8df85
commit
7ccb6dc2d3
@ -56,24 +56,25 @@ typedef struct
|
|||||||
static int4
|
static int4
|
||||||
gettoken(WORKSTATE *state, int4 *val)
|
gettoken(WORKSTATE *state, int4 *val)
|
||||||
{
|
{
|
||||||
char nnn[16],
|
char nnn[16];
|
||||||
*curnnn;
|
int innn;
|
||||||
|
|
||||||
*val = 0; /* default result */
|
*val = 0; /* default result */
|
||||||
|
|
||||||
curnnn = nnn;
|
innn = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
if (innn >= sizeof(nnn))
|
||||||
|
return ERR; /* buffer overrun => syntax error */
|
||||||
switch (state->state)
|
switch (state->state)
|
||||||
{
|
{
|
||||||
case WAITOPERAND:
|
case WAITOPERAND:
|
||||||
curnnn = nnn;
|
innn = 0;
|
||||||
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
|
if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
|
||||||
*(state->buf) == '-')
|
*(state->buf) == '-')
|
||||||
{
|
{
|
||||||
state->state = WAITENDOPERAND;
|
state->state = WAITENDOPERAND;
|
||||||
*curnnn = *(state->buf);
|
nnn[innn++] = *(state->buf);
|
||||||
curnnn++;
|
|
||||||
}
|
}
|
||||||
else if (*(state->buf) == '!')
|
else if (*(state->buf) == '!')
|
||||||
{
|
{
|
||||||
@ -93,13 +94,18 @@ gettoken(WORKSTATE *state, int4 *val)
|
|||||||
case WAITENDOPERAND:
|
case WAITENDOPERAND:
|
||||||
if (*(state->buf) >= '0' && *(state->buf) <= '9')
|
if (*(state->buf) >= '0' && *(state->buf) <= '9')
|
||||||
{
|
{
|
||||||
*curnnn = *(state->buf);
|
nnn[innn++] = *(state->buf);
|
||||||
curnnn++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*curnnn = '\0';
|
long lval;
|
||||||
*val = (int4) atoi(nnn);
|
|
||||||
|
nnn[innn] = '\0';
|
||||||
|
errno = 0;
|
||||||
|
lval = strtol(nnn, NULL, 0);
|
||||||
|
*val = (int4) lval;
|
||||||
|
if (errno != 0 || (long) *val != lval)
|
||||||
|
return ERR;
|
||||||
state->state = WAITOPERATOR;
|
state->state = WAITOPERATOR;
|
||||||
return (state->count && *(state->buf) == '\0')
|
return (state->count && *(state->buf) == '\0')
|
||||||
? ERR : VAL;
|
? ERR : VAL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user