From ad0009e7be27489f5acc0a36217d9ea8f3db2b14 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 30 May 2012 23:47:57 -0400
Subject: [PATCH] Force PL and range-type support functions to be owned by a
 superuser.

We allow non-superusers to create procedural languages (with restrictions)
and range datatypes.  Previously, the automatically-created support
functions for these objects ended up owned by the creating user.  This
represents a rather considerable security hazard, because the owning user
might be able to alter a support function's definition in such a way as to
crash the server, inject trojan-horse SQL code, or even execute arbitrary
C code directly.  It appears that right now the only actually exploitable
problem is the infinite-recursion bug fixed in the previous patch for
CVE-2012-2655.  However, it's not hard to imagine that future additions of
more ALTER FUNCTION capability might unintentionally open up new hazards.
To forestall future problems, cause these support functions to be owned by
the bootstrap superuser, not the user creating the parent object.
---
 src/backend/catalog/pg_aggregate.c  | 1 +
 src/backend/catalog/pg_proc.c       | 2 +-
 src/backend/commands/functioncmds.c | 1 +
 src/backend/commands/proclang.c     | 4 ++++
 src/backend/commands/typecmds.c     | 2 ++
 src/include/catalog/pg_proc_fn.h    | 1 +
 6 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 9ff70a52e6c..0b393cf6cee 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -233,6 +233,7 @@ AggregateCreate(const char *aggName,
 							  false,	/* no replacement */
 							  false,	/* doesn't return a set */
 							  finaltype,		/* returnType */
+							  GetUserId(),		/* proowner */
 							  INTERNALlanguageId,		/* languageObjectId */
 							  InvalidOid,		/* no validator */
 							  "aggregate_dummy",		/* placeholder proc */
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 1fffe1c6ac3..ae71b939175 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -69,6 +69,7 @@ ProcedureCreate(const char *procedureName,
 				bool replace,
 				bool returnsSet,
 				Oid returnType,
+				Oid proowner,
 				Oid languageObjectId,
 				Oid languageValidator,
 				const char *prosrc,
@@ -100,7 +101,6 @@ ProcedureCreate(const char *procedureName,
 	bool		internalInParam = false;
 	bool		internalOutParam = false;
 	Oid			variadicType = InvalidOid;
-	Oid			proowner = GetUserId();
 	Acl		   *proacl = NULL;
 	Relation	rel;
 	HeapTuple	tup;
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 5f1c19eb375..ff0836c141e 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -978,6 +978,7 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
 					stmt->replace,
 					returnsSet,
 					prorettype,
+					GetUserId(),
 					languageOid,
 					languageValidator,
 					prosrc_str, /* converted to text later */
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 41775fd8674..5d2e7dc1951 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -18,6 +18,7 @@
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
+#include "catalog/pg_authid.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_pltemplate.h"
@@ -124,6 +125,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 										 false, /* replace */
 										 false, /* returnsSet */
 										 LANGUAGE_HANDLEROID,
+										 BOOTSTRAP_SUPERUSERID,
 										 ClanguageId,
 										 F_FMGR_C_VALIDATOR,
 										 pltemplate->tmplhandler,
@@ -160,6 +162,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 											false,		/* replace */
 											false,		/* returnsSet */
 											VOIDOID,
+											BOOTSTRAP_SUPERUSERID,
 											ClanguageId,
 											F_FMGR_C_VALIDATOR,
 											pltemplate->tmplinline,
@@ -199,6 +202,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 										 false, /* replace */
 										 false, /* returnsSet */
 										 VOIDOID,
+										 BOOTSTRAP_SUPERUSERID,
 										 ClanguageId,
 										 F_FMGR_C_VALIDATOR,
 										 pltemplate->tmplvalidator,
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 140b3f851e9..77559842e53 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -38,6 +38,7 @@
 #include "catalog/dependency.h"
 #include "catalog/heap.h"
 #include "catalog/indexing.h"
+#include "catalog/pg_authid.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_depend.h"
@@ -1513,6 +1514,7 @@ makeRangeConstructors(const char *name, Oid namespace,
 								  false,		/* replace */
 								  false,		/* returns set */
 								  rangeOid,		/* return type */
+								  BOOTSTRAP_SUPERUSERID,		/* proowner */
 								  INTERNALlanguageId,	/* language */
 								  F_FMGR_INTERNAL_VALIDATOR,	/* language validator */
 								  prosrc[i],	/* prosrc */
diff --git a/src/include/catalog/pg_proc_fn.h b/src/include/catalog/pg_proc_fn.h
index 04fa64519da..fcd09e7059c 100644
--- a/src/include/catalog/pg_proc_fn.h
+++ b/src/include/catalog/pg_proc_fn.h
@@ -21,6 +21,7 @@ extern Oid ProcedureCreate(const char *procedureName,
 				bool replace,
 				bool returnsSet,
 				Oid returnType,
+				Oid proowner,
 				Oid languageObjectId,
 				Oid languageValidator,
 				const char *prosrc,
-- 
GitLab