mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
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
67dbe720f6
commit
d6d145673f
@ -62,24 +62,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) == '!')
|
||||
{
|
||||
@ -99,13 +100,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;
|
||||
|
Loading…
Reference in New Issue
Block a user