From: Tom Lane Date: Sun, 12 Feb 2006 22:33:47 +0000 (+0000) Subject: Fix bug in SET SESSION AUTHORIZATION that allows unprivileged users to crash X-Git-Tag: REL7_3_14~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=118f54d06d62205aa742699b59dccffabd5fd826;p=thirdparty%2Fpostgresql.git Fix bug in SET SESSION AUTHORIZATION that allows unprivileged users to crash the server, if it has been compiled with Asserts enabled (CVE-2006-0553). Thanks to Akio Ishida for reporting this problem. --- diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index ff814c3208f..87f8953ee26 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.71.2.3 2005/06/05 01:49:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.71.2.4 2006/02/12 22:33:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -532,6 +532,8 @@ show_server_encoding(void) * that can be re-used directly. We store the string in the form of * NAMEDATALEN 'x's followed by the numeric userid --- this cannot conflict * with any valid user name, because of the NAMEDATALEN limit on names. + * (NOTE: we rely on guc.c to have properly truncated any incoming value, + * but not to truncate already-stored values. See GUC_IS_NAME processing.) */ const char * assign_session_authorization(const char *value, bool doit, bool interactive) diff --git a/src/backend/utils/mb/encnames.c b/src/backend/utils/mb/encnames.c index c74808b2c02..6dd0e6e638a 100644 --- a/src/backend/utils/mb/encnames.c +++ b/src/backend/utils/mb/encnames.c @@ -2,7 +2,7 @@ * Encoding names and routines for work with it. All * in this file is shared bedween FE and BE. * - * $Id: encnames.c,v 1.10.2.1 2002/12/09 17:45:17 momjian Exp $ + * $Id: encnames.c,v 1.10.2.2 2006/02/12 22:33:47 tgl Exp $ */ #ifdef FRONTEND #include "postgres_fe.h" @@ -436,7 +436,7 @@ pg_char_to_encname_struct(const char *name) if (name == NULL || *name == '\0') return NULL; - if (strlen(name) > NAMEDATALEN) + if (strlen(name) >= NAMEDATALEN) { #ifdef FRONTEND fprintf(stderr, "pg_char_to_encname_struct(): encoding name too long"); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b49b36565e6..af64f0ad34f 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.99.2.5 2003/04/04 00:32:57 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.99.2.6 2006/02/12 22:33:47 tgl Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut . @@ -170,6 +170,7 @@ struct config_generic #define GUC_LIST_QUOTE 0x0002 /* double-quote list elements */ #define GUC_NO_SHOW_ALL 0x0004 /* exclude from SHOW ALL */ #define GUC_NO_RESET_ALL 0x0008 /* exclude from RESET ALL */ +#define GUC_IS_NAME 0x0010 /* limit string to NAMEDATALEN-1 */ /* bit values in status field */ #define GUC_HAVE_TENTATIVE 0x0001 /* tentative value is defined */ @@ -736,7 +737,7 @@ static struct config_string ConfigureNamesString[] = { { - {"client_encoding", PGC_USERSET}, &client_encoding_string, + {"client_encoding", PGC_USERSET, GUC_IS_NAME}, &client_encoding_string, "SQL_ASCII", assign_client_encoding, NULL }, @@ -799,7 +800,7 @@ static struct config_string }, { - {"server_encoding", PGC_USERSET}, &server_encoding_string, + {"server_encoding", PGC_USERSET, GUC_IS_NAME}, &server_encoding_string, "SQL_ASCII", assign_server_encoding, show_server_encoding }, @@ -809,7 +810,7 @@ static struct config_string }, { - {"session_authorization", PGC_USERSET, GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL}, + {"session_authorization", PGC_USERSET, GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL}, &session_authorization_string, NULL, assign_session_authorization, show_session_authorization }, @@ -1907,6 +1908,18 @@ set_config_option(const char *name, const char *value, elog(elevel, "out of memory"); return false; } + /* + * The only sort of "parsing" check we need to do is + * apply truncation if GUC_IS_NAME. + */ + if (conf->gen.flags & GUC_IS_NAME) + { + int len; + + len = pg_mbcliplen(newval, strlen(newval), + NAMEDATALEN-1); + newval[len] = '\0'; + } } else if (conf->reset_val) {