Commit a2160c5e authored by Tom Lane's avatar Tom Lane

Add tests to enlargeStringInfo() to avoid possible buffer-overrun or

infinite-loop problems if a bogus data length is passed.
parent 5ddbe904
...@@ -9,13 +9,14 @@ ...@@ -9,13 +9,14 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/lib/stringinfo.c,v 1.37 2003/11/29 22:39:42 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/lib/stringinfo.c,v 1.38 2004/05/11 20:07:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "utils/memutils.h"
/* /*
...@@ -220,7 +221,20 @@ enlargeStringInfo(StringInfo str, int needed) ...@@ -220,7 +221,20 @@ enlargeStringInfo(StringInfo str, int needed)
{ {
int newlen; int newlen;
/*
* Guard against ridiculous "needed" values, which can occur if we're
* fed bogus data. Without this, we can get an overflow or infinite
* loop in the following.
*/
if (needed < 0 ||
((Size) needed) >= (MaxAllocSize - (Size) str->len))
elog(ERROR, "invalid string enlargement request size %d",
needed);
needed += str->len + 1; /* total space required now */ needed += str->len + 1; /* total space required now */
/* Because of the above test, we now have needed <= MaxAllocSize */
if (needed <= str->maxlen) if (needed <= str->maxlen)
return; /* got enough space already */ return; /* got enough space already */
...@@ -234,6 +248,14 @@ enlargeStringInfo(StringInfo str, int needed) ...@@ -234,6 +248,14 @@ enlargeStringInfo(StringInfo str, int needed)
while (needed > newlen) while (needed > newlen)
newlen = 2 * newlen; newlen = 2 * newlen;
/*
* Clamp to MaxAllocSize in case we went past it. Note we are assuming
* here that MaxAllocSize <= INT_MAX/2, else the above loop could
* overflow. We will still have newlen >= needed.
*/
if (newlen > (int) MaxAllocSize)
newlen = (int) MaxAllocSize;
str->data = (char *) repalloc(str->data, newlen); str->data = (char *) repalloc(str->data, newlen);
str->maxlen = newlen; str->maxlen = newlen;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment