Probably security hole in postgresql-7.4.1 - Mailing list pgsql-hackers

From Ken Ashcraft
Subject Probably security hole in postgresql-7.4.1
Date
Msg-id 1082412849.6563.18.camel@dns.coverity.int
Whole thread Raw
Responses Re: Probably security hole in postgresql-7.4.1
List pgsql-hackers
I work at Coverity where we use static analysis to find bugs in
software.  I ran a security checker over postgresql-7.4.1 and I think I
found a security hole.  I'm not familiar with the postgres source, so
this report may be false.  My interpretation of the code follows.

I'd appreciate your feedback,
Ken Ashcraft

In the code below, fld_size gets copied in from a user specified file. 
It is passed as the 'needed' parameter to enlargeStringInfo().  If
needed is a very large positive value, the addition 'needed += str->len
+ 1;' could cause an overflow, making needed a negative number. 
enlargeStringInfo() would quickly return, thinking that enough memory
was present.  However, the call to CopyGetData() uses the large,
positive fld_size, resulting in a buffer overflow, assuming that the
user's file has enough data.


/home/kash/user-progs/postgres/postgresql-7.4.1/src/backend/commands/copy.c:2050:CopyReadBinaryAttribute: ERROR:TAINT:
2030:2050:Passingunbounded user value "fld_size" as arg 1 to function "enlargeStringInfo", which uses it unsafely in
model[SOURCE_MODEL=(lib,CopyGetInt32,user,taint)] [SINK_MODEL=(lib,enlargeStringInfo,user,trustingsink)] [BOUNDS= Upper
boundon line 2040]   [PATH=] 
 
                    bool *isnull)
{int32        fld_size;Datum        result;

Start --->fld_size = CopyGetInt32();
... DELETED 14 lines ...
/* reset attribute_buf to empty, and load raw data in it */attribute_buf.len = 0;attribute_buf.data[0] =
'\0';attribute_buf.cursor= 0;
 

Error --->enlargeStringInfo(&attribute_buf, fld_size);
CopyGetData(attribute_buf.data, fld_size);if (CopyGetEof())
-------------------

enlargeStringInfo(StringInfo str, int needed)
{int            newlen;
needed += str->len + 1;        /* total space required now */if (needed <= str->maxlen)    return;
/*got enough space already */
 
/* * We don't want to allocate just a little more space with each * append; for efficiency, double the buffer size each
timeit * overflows. Actually, we might need to more than double it if * 'needed' is big... */newlen = 2 *
str->maxlen;while(needed > newlen)    newlen = 2 * newlen;
 
str->data = (char *) repalloc(str->data, newlen);
str->maxlen = newlen;
}




pgsql-hackers by date:

Previous
From: Kenneth Marshall
Date:
Subject: Re: Why are these ARC variables per-backend?
Next
From: Bruce Momjian
Date:
Subject: Re: Triggers on system tables