aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch')
-rw-r--r--meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch267
1 files changed, 0 insertions, 267 deletions
diff --git a/meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch b/meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch
deleted file mode 100644
index cc2183a2ab..0000000000
--- a/meta-oe/recipes-support/postgresql/files/0004-Prevent-privilege-escalation-in-explicit-calls-to-PL.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-From 1d701d28a796ea2d1a4d2be9e9ee06209eaea040 Mon Sep 17 00:00:00 2001
-From: Noah Misch <noah@leadboat.com>
-Date: Mon, 17 Feb 2014 09:33:31 -0500
-Subject: [PATCH] Prevent privilege escalation in explicit calls to PL
- validators.
-
-commit 1d701d28a796ea2d1a4d2be9e9ee06209eaea040 REL9_2_STABLE
-
-The primary role of PL validators is to be called implicitly during
-CREATE FUNCTION, but they are also normal functions that a user can call
-explicitly. Add a permissions check to each validator to ensure that a
-user cannot use explicit validator calls to achieve things he could not
-otherwise achieve. Back-patch to 8.4 (all supported versions).
-Non-core procedural language extensions ought to make the same two-line
-change to their own validators.
-
-Andres Freund, reviewed by Tom Lane and Noah Misch.
-
-Security: CVE-2014-0061
-
-Upstream-Status: Backport
-Signed-off-by: Kai Kang <kai.kang@windriver.com>
----
- doc/src/sgml/plhandler.sgml | 5 ++-
- src/backend/catalog/pg_proc.c | 9 ++++
- src/backend/commands/functioncmds.c | 1 -
- src/backend/utils/fmgr/fmgr.c | 84 +++++++++++++++++++++++++++++++++++
- src/include/fmgr.h | 1 +
- src/pl/plperl/plperl.c | 4 ++
- src/pl/plpgsql/src/pl_handler.c | 3 +
- src/pl/plpython/plpy_main.c | 4 ++
- 8 files changed, 109 insertions(+), 2 deletions(-)
-
-diff --git a/doc/src/sgml/plhandler.sgml b/doc/src/sgml/plhandler.sgml
-index 024ef9d..aa4bba3 100644
---- a/doc/src/sgml/plhandler.sgml
-+++ b/doc/src/sgml/plhandler.sgml
-@@ -178,7 +178,10 @@ CREATE LANGUAGE plsample
- or updated a function written in the procedural language.
- The passed-in OID is the OID of the function's <classname>pg_proc</>
- row. The validator must fetch this row in the usual way, and do
-- whatever checking is appropriate. Typical checks include verifying
-+ whatever checking is appropriate.
-+ First, call <function>CheckFunctionValidatorAccess()</> to diagnose
-+ explicit calls to the validator that the user could not achieve through
-+ <command>CREATE FUNCTION</>. Typical checks then include verifying
- that the function's argument and result types are supported by the
- language, and that the function's body is syntactically correct
- in the language. If the validator finds the function to be okay,
-diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
-index 3812408..3124868 100644
---- a/src/backend/catalog/pg_proc.c
-+++ b/src/backend/catalog/pg_proc.c
-@@ -718,6 +718,9 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
- Datum tmp;
- char *prosrc;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- /*
- * We do not honor check_function_bodies since it's unlikely the function
- * name will be found later if it isn't there now.
-@@ -763,6 +766,9 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
- char *prosrc;
- char *probin;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- /*
- * It'd be most consistent to skip the check if !check_function_bodies,
- * but the purpose of that switch is to be helpful for pg_dump loading,
-@@ -814,6 +820,9 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
- bool haspolyarg;
- int i;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "cache lookup failed for function %u", funcoid);
-diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
-index 9ba6dd8..ea74b5e 100644
---- a/src/backend/commands/functioncmds.c
-+++ b/src/backend/commands/functioncmds.c
-@@ -997,7 +997,6 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
- prorows);
- }
-
--
- /*
- * Guts of function deletion.
- *
-diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
-index 2ec63fa..8d6f183 100644
---- a/src/backend/utils/fmgr/fmgr.c
-+++ b/src/backend/utils/fmgr/fmgr.c
-@@ -24,6 +24,7 @@
- #include "miscadmin.h"
- #include "nodes/nodeFuncs.h"
- #include "pgstat.h"
-+#include "utils/acl.h"
- #include "utils/builtins.h"
- #include "utils/fmgrtab.h"
- #include "utils/guc.h"
-@@ -2445,3 +2446,86 @@ get_call_expr_arg_stable(Node *expr, int argnum)
-
- return false;
- }
-+
-+/*-------------------------------------------------------------------------
-+ * Support routines for procedural language implementations
-+ *-------------------------------------------------------------------------
-+ */
-+
-+/*
-+ * Verify that a validator is actually associated with the language of a
-+ * particular function and that the user has access to both the language and
-+ * the function. All validators should call this before doing anything
-+ * substantial. Doing so ensures a user cannot achieve anything with explicit
-+ * calls to validators that he could not achieve with CREATE FUNCTION or by
-+ * simply calling an existing function.
-+ *
-+ * When this function returns false, callers should skip all validation work
-+ * and call PG_RETURN_VOID(). This never happens at present; it is reserved
-+ * for future expansion.
-+ *
-+ * In particular, checking that the validator corresponds to the function's
-+ * language allows untrusted language validators to assume they process only
-+ * superuser-chosen source code. (Untrusted language call handlers, by
-+ * definition, do assume that.) A user lacking the USAGE language privilege
-+ * would be unable to reach the validator through CREATE FUNCTION, so we check
-+ * that to block explicit calls as well. Checking the EXECUTE privilege on
-+ * the function is often superfluous, because most users can clone the
-+ * function to get an executable copy. It is meaningful against users with no
-+ * database TEMP right and no permanent schema CREATE right, thereby unable to
-+ * create any function. Also, if the function tracks persistent state by
-+ * function OID or name, validating the original function might permit more
-+ * mischief than creating and validating a clone thereof.
-+ */
-+bool
-+CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
-+{
-+ HeapTuple procTup;
-+ HeapTuple langTup;
-+ Form_pg_proc procStruct;
-+ Form_pg_language langStruct;
-+ AclResult aclresult;
-+
-+ /* Get the function's pg_proc entry */
-+ procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionOid));
-+ if (!HeapTupleIsValid(procTup))
-+ elog(ERROR, "cache lookup failed for function %u", functionOid);
-+ procStruct = (Form_pg_proc) GETSTRUCT(procTup);
-+
-+ /*
-+ * Fetch pg_language entry to know if this is the correct validation
-+ * function for that pg_proc entry.
-+ */
-+ langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(procStruct->prolang));
-+ if (!HeapTupleIsValid(langTup))
-+ elog(ERROR, "cache lookup failed for language %u", procStruct->prolang);
-+ langStruct = (Form_pg_language) GETSTRUCT(langTup);
-+
-+ if (langStruct->lanvalidator != validatorOid)
-+ ereport(ERROR,
-+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-+ errmsg("language validation function %u called for language %u instead of %u",
-+ validatorOid, procStruct->prolang,
-+ langStruct->lanvalidator)));
-+
-+ /* first validate that we have permissions to use the language */
-+ aclresult = pg_language_aclcheck(procStruct->prolang, GetUserId(),
-+ ACL_USAGE);
-+ if (aclresult != ACLCHECK_OK)
-+ aclcheck_error(aclresult, ACL_KIND_LANGUAGE,
-+ NameStr(langStruct->lanname));
-+
-+ /*
-+ * Check whether we are allowed to execute the function itself. If we can
-+ * execute it, there should be no possible side-effect of
-+ * compiling/validation that execution can't have.
-+ */
-+ aclresult = pg_proc_aclcheck(functionOid, GetUserId(), ACL_EXECUTE);
-+ if (aclresult != ACLCHECK_OK)
-+ aclcheck_error(aclresult, ACL_KIND_PROC, NameStr(procStruct->proname));
-+
-+ ReleaseSysCache(procTup);
-+ ReleaseSysCache(langTup);
-+
-+ return true;
-+}
-diff --git a/src/include/fmgr.h b/src/include/fmgr.h
-index 0a25776..f944cc6 100644
---- a/src/include/fmgr.h
-+++ b/src/include/fmgr.h
-@@ -624,6 +624,7 @@ extern Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum);
- extern Oid get_call_expr_argtype(fmNodePtr expr, int argnum);
- extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum);
- extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum);
-+extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
-
- /*
- * Routines in dfmgr.c
-diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
-index 7c2aee9..49d50c4 100644
---- a/src/pl/plperl/plperl.c
-+++ b/src/pl/plperl/plperl.c
-@@ -1847,6 +1847,9 @@ plperl_validator(PG_FUNCTION_ARGS)
- bool istrigger = false;
- int i;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- /* Get the new function's pg_proc entry */
- tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
- if (!HeapTupleIsValid(tuple))
-@@ -1926,6 +1929,7 @@ PG_FUNCTION_INFO_V1(plperlu_validator);
- Datum
- plperlu_validator(PG_FUNCTION_ARGS)
- {
-+ /* call plperl validator with our fcinfo so it gets our oid */
- return plperl_validator(fcinfo);
- }
-
-diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c
-index 022ec3f..00b1a6f 100644
---- a/src/pl/plpgsql/src/pl_handler.c
-+++ b/src/pl/plpgsql/src/pl_handler.c
-@@ -227,6 +227,9 @@ plpgsql_validator(PG_FUNCTION_ARGS)
- bool istrigger = false;
- int i;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- /* Get the new function's pg_proc entry */
- tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
- if (!HeapTupleIsValid(tuple))
-diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
-index c4de762..3847847 100644
---- a/src/pl/plpython/plpy_main.c
-+++ b/src/pl/plpython/plpy_main.c
-@@ -159,6 +159,9 @@ plpython_validator(PG_FUNCTION_ARGS)
- Form_pg_proc procStruct;
- bool is_trigger;
-
-+ if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
-+ PG_RETURN_VOID();
-+
- if (!check_function_bodies)
- {
- PG_RETURN_VOID();
-@@ -184,6 +187,7 @@ plpython_validator(PG_FUNCTION_ARGS)
- Datum
- plpython2_validator(PG_FUNCTION_ARGS)
- {
-+ /* call plpython validator with our fcinfo so it gets our oid */
- return plpython_validator(fcinfo);
- }
- #endif /* PY_MAJOR_VERSION < 3 */
---
-1.7.5.4
-