1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

Tweak libpq to avoid crashing due to incorrect buffer size calculation when

we are on a 64-bit machine (ie, size_t is wider than int) and someone passes
in a query string that approaches or exceeds INT_MAX bytes.  Also, just for
paranoia's sake, guard against similar overflows in sizing the input buffer.

The backend will not in the foreseeable future be prepared to send or receive
strings exceeding 1GB, so I didn't take the more invasive step of switching
all the buffer index variables from int to size_t; though someday we might
want to do that.

I have a suspicion that this is not the only such bug in libpq, but this
fix is enough to take care of the crash reported by Francisco Reyes.
This commit is contained in:
Tom Lane
2008-05-29 22:02:44 +00:00
parent 5914140a3b
commit 02ac305405
5 changed files with 30 additions and 25 deletions

View File

@ -23,7 +23,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.133 2008/01/01 19:46:00 momjian Exp $
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.134 2008/05/29 22:02:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -278,12 +278,12 @@ pqPutInt(int value, size_t bytes, PGconn *conn)
* Returns 0 on success, EOF if failed to enlarge buffer
*/
int
pqCheckOutBufferSpace(int bytes_needed, PGconn *conn)
pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
{
int newsize = conn->outBufSize;
char *newbuf;
if (bytes_needed <= newsize)
if (bytes_needed <= (size_t) newsize)
return 0;
/*
@ -296,9 +296,9 @@ pqCheckOutBufferSpace(int bytes_needed, PGconn *conn)
do
{
newsize *= 2;
} while (bytes_needed > newsize && newsize > 0);
} while (newsize > 0 && bytes_needed > (size_t) newsize);
if (bytes_needed <= newsize)
if (newsize > 0 && bytes_needed <= (size_t) newsize)
{
newbuf = realloc(conn->outBuffer, newsize);
if (newbuf)
@ -314,9 +314,9 @@ pqCheckOutBufferSpace(int bytes_needed, PGconn *conn)
do
{
newsize += 8192;
} while (bytes_needed > newsize && newsize > 0);
} while (newsize > 0 && bytes_needed > (size_t) newsize);
if (bytes_needed <= newsize)
if (newsize > 0 && bytes_needed <= (size_t) newsize)
{
newbuf = realloc(conn->outBuffer, newsize);
if (newbuf)
@ -341,12 +341,12 @@ pqCheckOutBufferSpace(int bytes_needed, PGconn *conn)
* Returns 0 on success, EOF if failed to enlarge buffer
*/
int
pqCheckInBufferSpace(int bytes_needed, PGconn *conn)
pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
{
int newsize = conn->inBufSize;
char *newbuf;
if (bytes_needed <= newsize)
if (bytes_needed <= (size_t) newsize)
return 0;
/*
@ -359,9 +359,9 @@ pqCheckInBufferSpace(int bytes_needed, PGconn *conn)
do
{
newsize *= 2;
} while (bytes_needed > newsize && newsize > 0);
} while (newsize > 0 && bytes_needed > (size_t) newsize);
if (bytes_needed <= newsize)
if (newsize > 0 && bytes_needed <= (size_t) newsize)
{
newbuf = realloc(conn->inBuffer, newsize);
if (newbuf)
@ -377,9 +377,9 @@ pqCheckInBufferSpace(int bytes_needed, PGconn *conn)
do
{
newsize += 8192;
} while (bytes_needed > newsize && newsize > 0);
} while (newsize > 0 && bytes_needed > (size_t) newsize);
if (bytes_needed <= newsize)
if (newsize > 0 && bytes_needed <= (size_t) newsize)
{
newbuf = realloc(conn->inBuffer, newsize);
if (newbuf)
@ -572,7 +572,7 @@ pqReadData(PGconn *conn)
*/
if (conn->inBufSize - conn->inEnd < 8192)
{
if (pqCheckInBufferSpace(conn->inEnd + 8192, conn))
if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
{
/*
* We don't insist that the enlarge worked, but we need some room