diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-05-11 20:07:38 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-05-11 20:07:38 +0000 |
commit | 5e027b19cd79c944a3fb1b9024745d563c9e57cb (patch) | |
tree | 58ba44e4acf2205bc203d0bad5bdaad9b6dd3867 | |
parent | b8de9b216ffaa52d6c4cac09292f2c0e9fbf8c53 (diff) | |
download | postgresql-5e027b19cd79c944a3fb1b9024745d563c9e57cb.tar.gz postgresql-5e027b19cd79c944a3fb1b9024745d563c9e57cb.zip |
Add tests to enlargeStringInfo() to avoid possible buffer-overrun or
infinite-loop problems if a bogus data length is passed.
-rw-r--r-- | src/backend/lib/stringinfo.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c index 3d7c24bb4fa..d23e6a254a9 100644 --- a/src/backend/lib/stringinfo.c +++ b/src/backend/lib/stringinfo.c @@ -9,13 +9,14 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: stringinfo.c,v 1.36 2003/08/04 02:39:59 momjian Exp $ + * $Id: stringinfo.c,v 1.36.4.1 2004/05/11 20:07:38 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include "lib/stringinfo.h" +#include "utils/memutils.h" /* @@ -220,7 +221,20 @@ enlargeStringInfo(StringInfo str, int needed) { 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 */ + + /* Because of the above test, we now have needed <= MaxAllocSize */ + if (needed <= str->maxlen) return; /* got enough space already */ @@ -234,6 +248,14 @@ enlargeStringInfo(StringInfo str, int needed) while (needed > 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->maxlen = newlen; |