Neil Conway <[EMAIL PROTECTED]> writes:
> Sir Mordred The Traitor <[EMAIL PROTECTED]> writes:
> > There exists a buffer overflow in a SET TIME ZONE command, that
> > allows an attacker to execute malicious code.
>
> Here's a patch for the problem. I also fixed some other potential
> buffer overruns nearby, and added a little paranoia to another routine
> that uses a statically sized buffer.
The handling of the TZ environmental variable is subject to a buffer
overrun. To see the problem, try:
export
TZ=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
postmaster -D /foo/bar&
psql
You get:
NOTICE: Buffer Leak: [26914] (freeNext=0, freePrev=0, rel=0/0, blockNum=0, flags=0x0,
refcount=0 1)
[ lots more NOTICEs ]
psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
A revised patch is attached that fixes the problem.
Cheers,
Neil
--
Neil Conway <[EMAIL PROTECTED]> || PGP Key ID: DB3C29FC
Index: src/backend/commands/variable.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/commands/variable.c,v
retrieving revision 1.57
diff -c -r1.57 variable.c
*** src/backend/commands/variable.c 9 Dec 2001 04:37:50 -0000 1.57
--- src/backend/commands/variable.c 21 Aug 2002 17:32:27 -0000
***************
*** 274,299 ****
show_datestyle(void)
{
char buf[64];
- strcpy(buf, "DateStyle is ");
switch (DateStyle)
{
case USE_ISO_DATES:
! strcat(buf, "ISO");
break;
case USE_SQL_DATES:
! strcat(buf, "SQL");
break;
case USE_GERMAN_DATES:
! strcat(buf, "German");
break;
default:
! strcat(buf, "Postgres");
break;
! };
! strcat(buf, " with ");
! strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)"));
! strcat(buf, " conventions");
elog(NOTICE, buf, NULL);
--- 274,299 ----
show_datestyle(void)
{
char buf[64];
+ char *dstyle;
switch (DateStyle)
{
case USE_ISO_DATES:
! dstyle = "ISO";
break;
case USE_SQL_DATES:
! dstyle = "SQL";
break;
case USE_GERMAN_DATES:
! dstyle = "German";
break;
default:
! dstyle = "Postgres";
break;
! }
!
! snprintf(buf, sizeof(buf), "DateStyle is %s with %s conventions",
! dstyle, EuroDates ? "European" : "US (NonEuropean");
elog(NOTICE, buf, NULL);
***************
*** 442,456 ****
{
/* found something? then save it for later */
if ((defaultTZ = getenv("TZ")) != NULL)
! strcpy(TZvalue, defaultTZ);
/* found nothing so mark with an invalid pointer */
else
defaultTZ = (char *) -1;
}
! strcpy(tzbuf, "TZ=");
! strcat(tzbuf, tok);
if (putenv(tzbuf) != 0)
elog(ERROR, "Unable to set TZ environment variable to %s", tok);
--- 442,455 ----
{
/* found something? then save it for later */
if ((defaultTZ = getenv("TZ")) != NULL)
! strncpy(TZvalue, defaultTZ, sizeof(TZvalue));
/* found nothing so mark with an invalid pointer */
else
defaultTZ = (char *) -1;
}
! snprintf(tzbuf, sizeof(tzbuf), "TZ=%s", tok);
if (putenv(tzbuf) != 0)
elog(ERROR, "Unable to set TZ environment variable to %s", tok);
***************
*** 513,520 ****
/* time zone was set and original explicit time zone available? */
else if (defaultTZ != (char *) -1)
{
! strcpy(tzbuf, "TZ=");
! strcat(tzbuf, TZvalue);
if (putenv(tzbuf) != 0)
elog(ERROR, "Unable to set TZ environment variable to %s", TZvalue);
tzset();
--- 512,518 ----
/* time zone was set and original explicit time zone available? */
else if (defaultTZ != (char *) -1)
{
! snprintf(tzbuf, sizeof(tzbuf), "TZ=%s", TZvalue);
if (putenv(tzbuf) != 0)
elog(ERROR, "Unable to set TZ environment variable to %s", TZvalue);
tzset();
Index: src/backend/utils/adt/nabstime.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/nabstime.c,v
retrieving revision 1.91
diff -c -r1.91 nabstime.c
*** src/backend/utils/adt/nabstime.c 25 Oct 2001 05:49:44 -0000 1.91
--- src/backend/utils/adt/nabstime.c 21 Aug 2002 17:32:27 -0000
***************
*** 145,165 ****
* XXX is there a better way to get local timezone string w/o
* tzname? - tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN, "%Z", tm);
#endif
/*
* XXX FreeBSD man pages indicate that this should work - thomas
* 1998-12-12
*/
! strcpy(CTZName, tm->tm_zone);
#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]);
#else /* neither HAVE_TM_ZONE nor
* HAVE_INT_TIMEZONE */
CTimeZone = tb.timezone * 60;
--- 145,165 ----
* XXX is there a better way to get local timezone string w/o
* tzname? - tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN + 1, "%Z", tm);
#endif
/*
* XXX FreeBSD man pages indicate that this should work - thomas
* 1998-12-12
*/
! 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);
! StrNCpy(CTZName, tzname[tm->tm_isdst], MAXTZLEN + 1);
#else /* neither HAVE_TM_ZONE nor
* HAVE_INT_TIMEZONE */
CTimeZone = tb.timezone * 60;
***************
*** 169,175 ****
* XXX does this work to get the local timezone string in V7? -
* tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
}
--- 169,175 ----
* XXX does this work to get the local timezone string in V7? -
* tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN + 1, "%Z", localtime(&now));
#endif
}
***************
*** 227,247 ****
* XXX is there a better way to get local timezone string w/o
* tzname? - tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN, "%Z", tm);
#endif
/*
* XXX FreeBSD man pages indicate that this should work - thomas
* 1998-12-12
*/
! strcpy(CTZName, tm->tm_zone);
#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]);
#else /* neither HAVE_TM_ZONE nor
* HAVE_INT_TIMEZONE */
CTimeZone = tb.timezone * 60;
--- 227,247 ----
* XXX is there a better way to get local timezone string w/o
* tzname? - tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN + 1, "%Z", tm);
#endif
/*
* XXX FreeBSD man pages indicate that this should work - thomas
* 1998-12-12
*/
! 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);
! StrNCpy(CTZName, tzname[tm->tm_isdst], MAXTZLEN + 1);
#else /* neither HAVE_TM_ZONE nor
* HAVE_INT_TIMEZONE */
CTimeZone = tb.timezone * 60;
***************
*** 251,257 ****
* XXX does this work to get the local timezone string in V7? -
* tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
};
--- 251,257 ----
* XXX does this work to get the local timezone string in V7? -
* tgl 97/03/18
*/
! strftime(CTZName, MAXTZLEN + 1, "%Z", localtime(&now));
#endif
};
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly