diff options
author | Bruce Momjian <bruce@momjian.us> | 2002-08-22 05:27:41 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2002-08-22 05:27:41 +0000 |
commit | cd9f392cd074dc06f095219b98baabcc16279a0b (patch) | |
tree | ccb4008a2c939c0db15cf687526aca54f1939fa3 | |
parent | 76fc795e5c51a1c0a090f47045ee46ef6d97e128 (diff) | |
download | postgresql-cd9f392cd074dc06f095219b98baabcc16279a0b.tar.gz postgresql-cd9f392cd074dc06f095219b98baabcc16279a0b.zip |
Apply Neil Conway's security patches to 7.2.X.
-rw-r--r-- | src/backend/commands/variable.c | 28 | ||||
-rw-r--r-- | src/backend/utils/adt/date.c | 12 | ||||
-rw-r--r-- | src/backend/utils/adt/nabstime.c | 26 | ||||
-rw-r--r-- | src/backend/utils/adt/oracle_compat.c | 22 | ||||
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 18 |
5 files changed, 72 insertions, 34 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 7d6300f4a91..8d1e8a1b3c5 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.57 2001/12/09 04:37:50 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.57.2.1 2002/08/22 05:27:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -274,26 +274,26 @@ static bool show_datestyle(void) { char buf[64]; + char *dstyle; - strcpy(buf, "DateStyle is "); switch (DateStyle) { case USE_ISO_DATES: - strcat(buf, "ISO"); + dstyle = "ISO"; break; case USE_SQL_DATES: - strcat(buf, "SQL"); + dstyle = "SQL"; break; case USE_GERMAN_DATES: - strcat(buf, "German"); + dstyle = "German"; break; default: - strcat(buf, "Postgres"); + dstyle = "Postgres"; break; - }; - strcat(buf, " with "); - strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)")); - strcat(buf, " conventions"); + } + + snprintf(buf, sizeof(buf), "DateStyle is %s with %s conventions", + dstyle, EuroDates ? "European" : "US (NonEuropean"); elog(NOTICE, buf, NULL); @@ -442,15 +442,14 @@ parse_timezone(List *args) { /* found something? then save it for later */ if ((defaultTZ = getenv("TZ")) != NULL) - strcpy(TZvalue, defaultTZ); + strncpy(TZvalue, defaultTZ, sizeof(TZvalue)); /* found nothing so mark with an invalid pointer */ else defaultTZ = (char *) -1; } - strcpy(tzbuf, "TZ="); - strcat(tzbuf, tok); + snprintf(tzbuf, sizeof(tzbuf), "TZ=%s", tok); if (putenv(tzbuf) != 0) elog(ERROR, "Unable to set TZ environment variable to %s", tok); @@ -513,8 +512,7 @@ reset_timezone(void) /* time zone was set and original explicit time zone available? */ else if (defaultTZ != (char *) -1) { - strcpy(tzbuf, "TZ="); - strcat(tzbuf, TZvalue); + snprintf(tzbuf, sizeof(tzbuf), "TZ=%s", TZvalue); if (putenv(tzbuf) != 0) elog(ERROR, "Unable to set TZ environment variable to %s", TZvalue); tzset(); diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index eed04217d69..24c603bd7ba 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.64.2.1 2002/03/15 23:37:48 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.64.2.2 2002/08/22 05:27:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,9 @@ date_in(PG_FUNCTION_ARGS) int ftype[MAXDATEFIELDS]; char lowstr[MAXDATELEN + 1]; + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad date external representation (too long) '%s'", str); + if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0)) elog(ERROR, "Bad date external representation '%s'", str); @@ -442,6 +445,9 @@ time_in(PG_FUNCTION_ARGS) int dtype; int ftype[MAXDATEFIELDS]; + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad time external representation (too long) '%s'", str); + if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, NULL) != 0)) elog(ERROR, "Bad time external representation '%s'", str); @@ -951,6 +957,10 @@ timetz_in(PG_FUNCTION_ARGS) int dtype; int ftype[MAXDATEFIELDS]; + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad time with time zone external representation" + " (too long) '%s'", str); + if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0)) elog(ERROR, "Bad time external representation '%s'", str); diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c index 3bbf5ec7c89..7244ad4d367 100644 --- a/src/backend/utils/adt/nabstime.c +++ b/src/backend/utils/adt/nabstime.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.91 2001/10/25 05:49:44 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.91.2.1 2002/08/22 05:27:41 momjian Exp $ * * NOTES * @@ -145,21 +145,21 @@ GetCurrentAbsoluteTime(void) * XXX is there a better way to get local timezone string w/o * tzname? - tgl 97/03/18 */ - strftime(CTZName, MAXTZLEN, "%Z", tm); + strftime(CTZName, MAXTZLEN + 1, "%Z", tm); #endif /* * XXX FreeBSD man pages indicate that this should work - thomas * 1998-12-12 */ - strcpy(CTZName, tm->tm_zone); + StrNCpy(CTZName, tm->tm_zone, MAXTZLEN + 1); #elif defined(HAVE_INT_TIMEZONE) tm = localtime(&now); CDayLight = tm->tm_isdst; CTimeZone = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL); - strcpy(CTZName, tzname[tm->tm_isdst]); + StrNCpy(CTZName, tzname[tm->tm_isdst], MAXTZLEN + 1); #else /* neither HAVE_TM_ZONE nor * HAVE_INT_TIMEZONE */ CTimeZone = tb.timezone * 60; @@ -169,7 +169,7 @@ GetCurrentAbsoluteTime(void) * XXX does this work to get the local timezone string in V7? - * tgl 97/03/18 */ - strftime(CTZName, MAXTZLEN, "%Z", localtime(&now)); + strftime(CTZName, MAXTZLEN + 1, "%Z", localtime(&now)); #endif } @@ -227,21 +227,21 @@ GetCurrentAbsoluteTimeUsec(int *usec) * XXX is there a better way to get local timezone string w/o * tzname? - tgl 97/03/18 */ - strftime(CTZName, MAXTZLEN, "%Z", tm); + strftime(CTZName, MAXTZLEN + 1, "%Z", tm); #endif /* * XXX FreeBSD man pages indicate that this should work - thomas * 1998-12-12 */ - strcpy(CTZName, tm->tm_zone); + StrNCpy(CTZName, tm->tm_zone, MAXTZLEN + 1); #elif defined(HAVE_INT_TIMEZONE) tm = localtime(&now); CDayLight = tm->tm_isdst; CTimeZone = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL); - strcpy(CTZName, tzname[tm->tm_isdst]); + StrNCpy(CTZName, tzname[tm->tm_isdst], MAXTZLEN + 1); #else /* neither HAVE_TM_ZONE nor * HAVE_INT_TIMEZONE */ CTimeZone = tb.timezone * 60; @@ -251,7 +251,7 @@ GetCurrentAbsoluteTimeUsec(int *usec) * XXX does this work to get the local timezone string in V7? - * tgl 97/03/18 */ - strftime(CTZName, MAXTZLEN, "%Z", localtime(&now)); + strftime(CTZName, MAXTZLEN + 1, "%Z", localtime(&now)); #endif }; @@ -503,8 +503,8 @@ nabstimein(PG_FUNCTION_ARGS) int nf, ftype[MAXDATEFIELDS]; - if (strlen(str) > MAXDATELEN) - elog(ERROR, "Bad (length) abstime external representation '%s'", str); + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad abstime external representation '%s' (too long)", str); if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0)) @@ -856,8 +856,8 @@ reltimein(PG_FUNCTION_ARGS) ftype[MAXDATEFIELDS]; char lowstr[MAXDATELEN + 1]; - if (strlen(str) > MAXDATELEN) - elog(ERROR, "Bad (length) reltime external representation '%s'", str); + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad reltime external representation '%s' (too long)", str); if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0)) diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index d4391f764fc..2f91e03e0ac 100644 --- a/src/backend/utils/adt/oracle_compat.c +++ b/src/backend/utils/adt/oracle_compat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.37 2002/01/08 17:03:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.37.2.1 2002/08/22 05:27:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -199,6 +199,11 @@ lpad(PG_FUNCTION_ARGS) #ifdef MULTIBYTE bytelen = pg_database_encoding_max_length() * len; + + /* check for integer overflow */ + if (len != 0 && bytelen / pg_database_encoding_max_length() != len) + elog(ERROR, "Requested length too large"); + ret = (text *) palloc(VARHDRSZ + bytelen); #else ret = (text *) palloc(VARHDRSZ + len); @@ -310,6 +315,11 @@ rpad(PG_FUNCTION_ARGS) #ifdef MULTIBYTE bytelen = pg_database_encoding_max_length() * len; + + /* Check for integer overflow */ + if (len != 0 && bytelen / pg_database_encoding_max_length() != len) + elog(ERROR, "Requested length too large"); + ret = (text *) palloc(VARHDRSZ + bytelen); #else ret = (text *) palloc(VARHDRSZ + len); @@ -997,6 +1007,16 @@ repeat(PG_FUNCTION_ARGS) slen = (VARSIZE(string) - VARHDRSZ); tlen = (VARHDRSZ + (count * slen)); + /* Check for integer overflow */ + if (slen != 0 && count != 0) + { + int check = count * slen; + int check2 = check + VARHDRSZ; + + if ((check / slen) != count || check2 <= check) + elog(ERROR, "Requested buffer is too large."); + } + result = (text *) palloc(tlen); VARATT_SIZEP(result) = tlen; diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index afd1963f1df..eb3a4195c3e 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.62.2.1 2002/03/05 03:45:43 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.62.2.2 2002/08/22 05:27:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -61,7 +61,10 @@ timestamp_in(PG_FUNCTION_ARGS) int nf; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; - char lowstr[MAXDATELEN + 1]; + char lowstr[MAXDATELEN + MAXDATEFIELDS]; + + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad timestamp external representation (too long) '%s'", str); if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0)) @@ -185,7 +188,11 @@ timestamptz_in(PG_FUNCTION_ARGS) int nf; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; - char lowstr[MAXDATELEN + 1]; + char lowstr[MAXDATELEN + MAXDATEFIELDS]; + + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad timestamp with time zone" + " external representation (too long) '%s'", str); if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0)) @@ -293,7 +300,10 @@ interval_in(PG_FUNCTION_ARGS) int nf; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; - char lowstr[MAXDATELEN + 1]; + char lowstr[MAXDATELEN + MAXDATEFIELDS]; + + if (strlen(str) >= sizeof(lowstr)) + elog(ERROR, "Bad interval external representation (too long) '%s'", str); tm->tm_year = 0; tm->tm_mon = 0; |