From 1564e92cea27a22ace7da635fe73fc23f96f8d4e Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Fri, 13 Jan 2006 18:06:45 +0000 Subject: [PATCH] Require the issuer of CREATE TYPE to own the functions mentioned in the type definition. Because use of a type's I/O conversion functions isn't access-checked, CREATE TYPE amounts to granting public execute permissions on the functions, and so allowing it to anybody means that someone could theoretically gain access to a function he's not supposed to be able to execute. The parameter-type restrictions already enforced by CREATE TYPE make it fairly unlikely that this oversight is meaningful in practice, but still it seems like a good idea to plug the hole going forward. Also, document the implicit grant just in case anybody gets the idea of building I/O functions that might need security restrictions. --- doc/src/sgml/ref/create_type.sgml | 13 ++++++++++++- src/backend/commands/typecmds.c | 26 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 1205605ca36..a39c244c6c7 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.59 2005/11/01 21:09:50 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.60 2006/01/13 18:06:45 tgl Exp $ PostgreSQL documentation --> @@ -446,6 +446,17 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> ( internally-created array type names. </para> + <para> + Because there are no restrictions on use of a data type once it's been + created, creating a base type is tantamount to granting public execute + permission on the functions mentioned in the type definition. (The creator + of the type is therefore required to own these functions.) This is usually + not an issue for the sorts of functions that are useful in a type + definition. But you might want to think twice before designing a type + in a way that would require <quote>secret</> information to be used + while converting it to or from external form. + </para> + <para> In <productname>PostgreSQL</productname> versions before 7.3, it was customary to avoid creating a shell type by replacing the diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 389fe133a58..143695252f4 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.85 2005/11/22 18:17:09 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.86 2006/01/13 18:06:45 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -330,6 +330,30 @@ DefineType(List *names, List *parameters) if (analyzeName) analyzeOid = findTypeAnalyzeFunction(analyzeName, typoid); + /* + * Check permissions on functions. We choose to require the creator/owner + * of a type to also own the underlying functions. Since creating a type + * is tantamount to granting public execute access on the functions, the + * minimum sane check would be for execute-with-grant-option. But we don't + * have a way to make the type go away if the grant option is revoked, so + * ownership seems better. + */ + if (inputOid && !pg_proc_ownercheck(inputOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + NameListToString(inputName)); + if (outputOid && !pg_proc_ownercheck(outputOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + NameListToString(outputName)); + if (receiveOid && !pg_proc_ownercheck(receiveOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + NameListToString(receiveName)); + if (sendOid && !pg_proc_ownercheck(sendOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + NameListToString(sendName)); + if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, + NameListToString(analyzeName)); + /* * now have TypeCreate do all the real work. */ -- GitLab