summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-02 00:03:44 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-02 00:03:44 +0000
commitf67497141888dfeea36401ba2a93d9bd74a6ecd7 (patch)
tree57844ea4dae02386e664850d9f0c150d8db24933 /src/backend/optimizer/util
parenta258f9c6de85b0a51cd6197cb9fb9e1354be1ba7 (diff)
Repair insufficiently careful type checking for SQL-language functions:
we should check that the function code returns the claimed result datatype every time we parse the function for execution. Formerly, for simple scalar result types we assumed the creation-time check was sufficient, but this fails if the function selects from a table that's been redefined since then, and even more obviously fails if check_function_bodies had been OFF. This is a significant security hole: not only can one trivially crash the backend, but with appropriate misuse of pass-by-reference datatypes it is possible to read out arbitrary locations in the server process's memory, which could allow retrieving database content the user should not be able to see. Our thanks to Jeff Trout for the initial report. Security: CVE-2007-0555
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/clauses.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 2c1b43266f8..66b6df85dff 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.186.4.4 2005/04/14 21:44:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.186.4.5 2007/02/02 00:03:44 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -2138,7 +2138,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
eval_const_expressions_context *context)
{
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
- bool polymorphic = false;
Oid argtypes[FUNC_MAX_ARGS];
char *src;
Datum tmp;
@@ -2179,15 +2178,10 @@ inline_function(Oid funcid, Oid result_type, List *args,
if (argtypes[i] == ANYARRAYOID ||
argtypes[i] == ANYELEMENTOID)
{
- polymorphic = true;
argtypes[i] = exprType((Node *) list_nth(args, i));
}
}
- if (funcform->prorettype == ANYARRAYOID ||
- funcform->prorettype == ANYELEMENTOID)
- polymorphic = true;
-
/*
* Setup error traceback support for ereport(). This is so that we
* can finger the function that bad information came from.
@@ -2260,16 +2254,14 @@ inline_function(Oid funcid, Oid result_type, List *args,
newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
/*
- * If the function has any arguments declared as polymorphic types,
- * then it wasn't type-checked at definition time; must do so now.
- * (This will raise an error if wrong, but that's okay since the
- * function would fail at runtime anyway. Note we do not try this
- * until we have verified that no rewriting was needed; that's
- * probably not important, but let's be careful.)
+ * Make sure the function (still) returns what it's declared to. This will
+ * raise an error if wrong, but that's okay since the function would fail
+ * at runtime anyway. Note we do not try this until we have verified that
+ * no rewriting was needed; that's probably not important, but let's be
+ * careful.
*/
- if (polymorphic)
- (void) check_sql_fn_retval(result_type, get_typtype(result_type),
- querytree_list, NULL);
+ (void) check_sql_fn_retval(result_type, get_typtype(result_type),
+ querytree_list, NULL);
/*
* Additional validity checks on the expression. It mustn't return a