aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/postgresql
diff options
context:
space:
mode:
authorKang Kai <kai.kang@windriver.com>2014-10-29 08:30:53 +0800
committerMartin Jansa <Martin.Jansa@gmail.com>2014-11-07 15:05:45 +0100
commitb89271147deaa0a409a5626d98681bb6f16528e2 (patch)
tree1dd40bb6d8d89c0254fe2f2422e3125c810201e7 /meta-oe/recipes-support/postgresql
parentcd4cd791999f9684c1b9b50d4ce600d9e8dd423d (diff)
downloadmeta-openembedded-b89271147deaa0a409a5626d98681bb6f16528e2.tar.gz
postgresql: add fix for CVE-2014-0060 Security Advisory
PostgreSQL before 8.4.20, 9.0.x before 9.0.16, 9.1.x before 9.1.12, 9.2.x before 9.2.7, and 9.3.x before 9.3.3 does not properly enforce the ADMIN OPTION restriction, which allows remote authenticated members of a role to add or remove arbitrary users to that role by calling the SET ROLE command before the associated GRANT command. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-0060 Signed-off-by: Yue Tao <Yue.Tao@windriver.com> Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'meta-oe/recipes-support/postgresql')
-rw-r--r--meta-oe/recipes-support/postgresql/files/0003-Shore-up-ADMIN-OPTION-restrictions.patch273
-rw-r--r--meta-oe/recipes-support/postgresql/postgresql.inc1
2 files changed, 274 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/postgresql/files/0003-Shore-up-ADMIN-OPTION-restrictions.patch b/meta-oe/recipes-support/postgresql/files/0003-Shore-up-ADMIN-OPTION-restrictions.patch
new file mode 100644
index 0000000000..abbe142495
--- /dev/null
+++ b/meta-oe/recipes-support/postgresql/files/0003-Shore-up-ADMIN-OPTION-restrictions.patch
@@ -0,0 +1,273 @@
+From 15a8f97b9d16aaf659f58c981242b9da591cf24c Mon Sep 17 00:00:00 2001
+From: Noah Misch <noah@leadboat.com>
+Date: Mon, 17 Feb 2014 09:33:31 -0500
+Subject: [PATCH] Shore up ADMIN OPTION restrictions.
+
+commit 15a8f97b9d16aaf659f58c981242b9da591cf24c REL9_2_STABLE
+
+Granting a role without ADMIN OPTION is supposed to prevent the grantee
+from adding or removing members from the granted role. Issuing SET ROLE
+before the GRANT bypassed that, because the role itself had an implicit
+right to add or remove members. Plug that hole by recognizing that
+implicit right only when the session user matches the current role.
+Additionally, do not recognize it during a security-restricted operation
+or during execution of a SECURITY DEFINER function. The restriction on
+SECURITY DEFINER is not security-critical. However, it seems best for a
+user testing his own SECURITY DEFINER function to see the same behavior
+others will see. Back-patch to 8.4 (all supported versions).
+
+The SQL standards do not conflate roles and users as PostgreSQL does;
+only SQL roles have members, and only SQL users initiate sessions. An
+application using PostgreSQL users and roles as SQL users and roles will
+never attempt to grant membership in the role that is the session user,
+so the implicit right to add or remove members will never arise.
+
+The security impact was mostly that a role member could revoke access
+from others, contrary to the wishes of his own grantor. Unapproved role
+member additions are less notable, because the member can still largely
+achieve that by creating a view or a SECURITY DEFINER function.
+
+Reviewed by Andres Freund and Tom Lane. Reported, independently, by
+Jonas Sundman and Noah Misch.
+
+Security: CVE-2014-0060
+
+
+Upstream-Status: Backport
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+---
+ doc/src/sgml/ref/grant.sgml | 12 ++++---
+ src/backend/commands/user.c | 11 ++++++-
+ src/backend/utils/adt/acl.c | 50 ++++++++++++++++++++++++------
+ src/test/regress/expected/privileges.out | 36 +++++++++++++++++++++-
+ src/test/regress/sql/privileges.sql | 29 ++++++++++++++++-
+ 5 files changed, 120 insertions(+), 18 deletions(-)
+
+diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml
+index fb81af4..2b5a843 100644
+--- a/doc/src/sgml/ref/grant.sgml
++++ b/doc/src/sgml/ref/grant.sgml
+@@ -396,11 +396,13 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
+ <para>
+ If <literal>WITH ADMIN OPTION</literal> is specified, the member can
+ in turn grant membership in the role to others, and revoke membership
+- in the role as well. Without the admin option, ordinary users cannot do
+- that. However,
+- database superusers can grant or revoke membership in any role to anyone.
+- Roles having <literal>CREATEROLE</> privilege can grant or revoke
+- membership in any role that is not a superuser.
++ in the role as well. Without the admin option, ordinary users cannot
++ do that. A role is not considered to hold <literal>WITH ADMIN
++ OPTION</literal> on itself, but it may grant or revoke membership in
++ itself from a database session where the session user matches the
++ role. Database superusers can grant or revoke membership in any role
++ to anyone. Roles having <literal>CREATEROLE</> privilege can grant
++ or revoke membership in any role that is not a superuser.
+ </para>
+
+ <para>
+diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
+index a22092c..39bf172 100644
+--- a/src/backend/commands/user.c
++++ b/src/backend/commands/user.c
+@@ -1334,7 +1334,16 @@ AddRoleMems(const char *rolename, Oid roleid,
+ rolename)));
+ }
+
+- /* XXX not sure about this check */
++ /*
++ * The role membership grantor of record has little significance at
++ * present. Nonetheless, inasmuch as users might look to it for a crude
++ * audit trail, let only superusers impute the grant to a third party.
++ *
++ * Before lifting this restriction, give the member == role case of
++ * is_admin_of_role() a fresh look. Ensure that the current role cannot
++ * use an explicit grantor specification to take advantage of the session
++ * user's self-admin right.
++ */
+ if (grantorId != GetUserId() && !superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
+index 1d6ae8b..9a52edb 100644
+--- a/src/backend/utils/adt/acl.c
++++ b/src/backend/utils/adt/acl.c
+@@ -4580,6 +4580,11 @@ pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode)
+ {
+ if (mode & ACL_GRANT_OPTION_FOR(ACL_CREATE))
+ {
++ /*
++ * XXX For roleid == role_oid, is_admin_of_role() also examines the
++ * session and call stack. That suits two-argument pg_has_role(), but
++ * it gives the three-argument version a lamentable whimsy.
++ */
+ if (is_admin_of_role(roleid, role_oid))
+ return ACLCHECK_OK;
+ }
+@@ -4897,11 +4902,9 @@ is_member_of_role_nosuper(Oid member, Oid role)
+
+
+ /*
+- * Is member an admin of role (directly or indirectly)? That is, is it
+- * a member WITH ADMIN OPTION?
+- *
+- * We could cache the result as for is_member_of_role, but currently this
+- * is not used in any performance-critical paths, so we don't.
++ * Is member an admin of role? That is, is member the role itself (subject to
++ * restrictions below), a member (directly or indirectly) WITH ADMIN OPTION,
++ * or a superuser?
+ */
+ bool
+ is_admin_of_role(Oid member, Oid role)
+@@ -4910,14 +4913,41 @@ is_admin_of_role(Oid member, Oid role)
+ List *roles_list;
+ ListCell *l;
+
+- /* Fast path for simple case */
+- if (member == role)
+- return true;
+-
+- /* Superusers have every privilege, so are part of every role */
+ if (superuser_arg(member))
+ return true;
+
++ if (member == role)
++ /*
++ * A role can admin itself when it matches the session user and we're
++ * outside any security-restricted operation, SECURITY DEFINER or
++ * similar context. SQL-standard roles cannot self-admin. However,
++ * SQL-standard users are distinct from roles, and they are not
++ * grantable like roles: PostgreSQL's role-user duality extends the
++ * standard. Checking for a session user match has the effect of
++ * letting a role self-admin only when it's conspicuously behaving
++ * like a user. Note that allowing self-admin under a mere SET ROLE
++ * would make WITH ADMIN OPTION largely irrelevant; any member could
++ * SET ROLE to issue the otherwise-forbidden command.
++ *
++ * Withholding self-admin in a security-restricted operation prevents
++ * object owners from harnessing the session user identity during
++ * administrative maintenance. Suppose Alice owns a database, has
++ * issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
++ * an alice-owned SECURITY DEFINER function that issues "REVOKE alice
++ * FROM carol". If he creates an expression index calling that
++ * function, Alice will attempt the REVOKE during each ANALYZE.
++ * Checking InSecurityRestrictedOperation() thwarts that attack.
++ *
++ * Withholding self-admin in SECURITY DEFINER functions makes their
++ * behavior independent of the calling user. There's no security or
++ * SQL-standard-conformance need for that restriction, though.
++ *
++ * A role cannot have actual WITH ADMIN OPTION on itself, because that
++ * would imply a membership loop. Therefore, we're done either way.
++ */
++ return member == GetSessionUserId() &&
++ !InLocalUserIdChange() && !InSecurityRestrictedOperation();
++
+ /*
+ * Find all the roles that member is a member of, including multi-level
+ * recursion. We build a list in the same way that is_member_of_role does
+diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
+index e8930cb..bc6d731 100644
+--- a/src/test/regress/expected/privileges.out
++++ b/src/test/regress/expected/privileges.out
+@@ -32,7 +32,7 @@ ALTER GROUP regressgroup1 ADD USER regressuser4;
+ ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
+ NOTICE: role "regressuser2" is already a member of role "regressgroup2"
+ ALTER GROUP regressgroup2 DROP USER regressuser2;
+-ALTER GROUP regressgroup2 ADD USER regressuser4;
++GRANT regressgroup2 TO regressuser4 WITH ADMIN OPTION;
+ -- test owner privileges
+ SET SESSION AUTHORIZATION regressuser1;
+ SELECT session_user, current_user;
+@@ -929,6 +929,40 @@ SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION')
+ t
+ (1 row)
+
++-- Admin options
++SET SESSION AUTHORIZATION regressuser4;
++CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS
++ 'GRANT regressgroup2 TO regressuser5';
++GRANT regressgroup2 TO regressuser5; -- ok: had ADMIN OPTION
++SET ROLE regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE suspended privilege
++ERROR: must have admin option on role "regressgroup2"
++SET SESSION AUTHORIZATION regressuser1;
++GRANT regressgroup2 TO regressuser5; -- fails: no ADMIN OPTION
++ERROR: must have admin option on role "regressgroup2"
++SELECT dogrant_ok(); -- ok: SECURITY DEFINER conveys ADMIN
++NOTICE: role "regressuser5" is already a member of role "regressgroup2"
++CONTEXT: SQL function "dogrant_ok" statement 1
++ dogrant_ok
++------------
++
++(1 row)
++
++SET ROLE regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE did not help
++ERROR: must have admin option on role "regressgroup2"
++SET SESSION AUTHORIZATION regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- ok: a role can self-admin
++NOTICE: role "regressuser5" is already a member of role "regressgroup2"
++CREATE FUNCTION dogrant_fails() RETURNS void LANGUAGE sql SECURITY DEFINER AS
++ 'GRANT regressgroup2 TO regressuser5';
++SELECT dogrant_fails(); -- fails: no self-admin in SECURITY DEFINER
++ERROR: must have admin option on role "regressgroup2"
++CONTEXT: SQL function "dogrant_fails" statement 1
++DROP FUNCTION dogrant_fails();
++SET SESSION AUTHORIZATION regressuser4;
++DROP FUNCTION dogrant_ok();
++REVOKE regressgroup2 FROM regressuser5;
+ -- has_sequence_privilege tests
+ \c -
+ CREATE SEQUENCE x_seq;
+diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
+index d4d328e..5f1018a 100644
+--- a/src/test/regress/sql/privileges.sql
++++ b/src/test/regress/sql/privileges.sql
+@@ -37,7 +37,7 @@ ALTER GROUP regressgroup1 ADD USER regressuser4;
+
+ ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
+ ALTER GROUP regressgroup2 DROP USER regressuser2;
+-ALTER GROUP regressgroup2 ADD USER regressuser4;
++GRANT regressgroup2 TO regressuser4 WITH ADMIN OPTION;
+
+ -- test owner privileges
+
+@@ -581,6 +581,33 @@ SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- false
+ SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
+
+
++-- Admin options
++
++SET SESSION AUTHORIZATION regressuser4;
++CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS
++ 'GRANT regressgroup2 TO regressuser5';
++GRANT regressgroup2 TO regressuser5; -- ok: had ADMIN OPTION
++SET ROLE regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE suspended privilege
++
++SET SESSION AUTHORIZATION regressuser1;
++GRANT regressgroup2 TO regressuser5; -- fails: no ADMIN OPTION
++SELECT dogrant_ok(); -- ok: SECURITY DEFINER conveys ADMIN
++SET ROLE regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- fails: SET ROLE did not help
++
++SET SESSION AUTHORIZATION regressgroup2;
++GRANT regressgroup2 TO regressuser5; -- ok: a role can self-admin
++CREATE FUNCTION dogrant_fails() RETURNS void LANGUAGE sql SECURITY DEFINER AS
++ 'GRANT regressgroup2 TO regressuser5';
++SELECT dogrant_fails(); -- fails: no self-admin in SECURITY DEFINER
++DROP FUNCTION dogrant_fails();
++
++SET SESSION AUTHORIZATION regressuser4;
++DROP FUNCTION dogrant_ok();
++REVOKE regressgroup2 FROM regressuser5;
++
++
+ -- has_sequence_privilege tests
+ \c -
+
+--
+1.7.5.4
+
diff --git a/meta-oe/recipes-support/postgresql/postgresql.inc b/meta-oe/recipes-support/postgresql/postgresql.inc
index 9b242e0476..d6a4cd781f 100644
--- a/meta-oe/recipes-support/postgresql/postgresql.inc
+++ b/meta-oe/recipes-support/postgresql/postgresql.inc
@@ -32,6 +32,7 @@ SRC_URI = "http://ftp.postgresql.org/pub/source/v${PV}/${BP}.tar.bz2 \
file://postgresql.service \
file://0001-Use-pkg-config-for-libxml2-detection.patch \
file://0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch \
+ file://0003-Shore-up-ADMIN-OPTION-restrictions.patch \
"
LEAD_SONAME = "libpq.so"