Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7bd7b20

Browse files
committed
Require superuser privilege to create base types (but not composites, enums,
or domains). This was already effectively required because you had to own the I/O functions, and the I/O functions pretty much have to be written in C since we don't let PL functions take or return cstring. But given the possible security consequences of a malicious type definition, it seems prudent to enforce superuser requirement directly. Per recent discussion.
1 parent c857298 commit 7bd7b20

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

doc/src/sgml/ref/create_type.sgml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.76 2008/07/30 19:35:12 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.77 2008/07/31 16:27:16 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -99,7 +99,13 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
9999

100100
<para>
101101
The third form of <command>CREATE TYPE</command> creates a new base type
102-
(scalar type). The parameters can appear in any order, not only that
102+
(scalar type). To create a new base type, you must be a superuser.
103+
(This restriction is made because an erroneous type definition could
104+
confuse or even crash the server.)
105+
</para>
106+
107+
<para>
108+
The parameters can appear in any order, not only that
103109
illustrated above, and most are optional. You must register
104110
two or more functions (using <command>CREATE FUNCTION</command>) before
105111
defining the type. The support functions
@@ -580,8 +586,8 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
580586
<para>
581587
Because there are no restrictions on use of a data type once it's been
582588
created, creating a base type is tantamount to granting public execute
583-
permission on the functions mentioned in the type definition. (The creator
584-
of the type is therefore required to own these functions.) This is usually
589+
permission on the functions mentioned in the type definition.
590+
This is usually
585591
not an issue for the sorts of functions that are useful in a type
586592
definition. But you might want to think twice before designing a type
587593
in a way that would require <quote>secret</> information to be used

src/backend/commands/typecmds.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.121 2008/07/30 19:35:13 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.122 2008/07/31 16:27:16 tgl Exp $
1212
*
1313
* DESCRIPTION
1414
* The "DefineFoo" routines take the parse tree and pick out the
@@ -92,14 +92,13 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
9292

9393
/*
9494
* DefineType
95-
* Registers a new type.
95+
* Registers a new base type.
9696
*/
9797
void
9898
DefineType(List *names, List *parameters)
9999
{
100100
char *typeName;
101101
Oid typeNamespace;
102-
AclResult aclresult;
103102
int16 internalLength = -1; /* default: variable-length */
104103
Oid elemType = InvalidOid;
105104
List *inputName = NIL;
@@ -130,14 +129,33 @@ DefineType(List *names, List *parameters)
130129
Oid resulttype;
131130
Relation pg_type;
132131

132+
/*
133+
* As of Postgres 8.4, we require superuser privilege to create a base
134+
* type. This is simple paranoia: there are too many ways to mess up the
135+
* system with an incorrect type definition (for instance, representation
136+
* parameters that don't match what the C code expects). In practice
137+
* it takes superuser privilege to create the I/O functions, and so the
138+
* former requirement that you own the I/O functions pretty much forced
139+
* superuserness anyway. We're just making doubly sure here.
140+
*
141+
* XXX re-enable NOT_USED code sections below if you remove this test.
142+
*/
143+
if (!superuser())
144+
ereport(ERROR,
145+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
146+
errmsg("must be superuser to create a base type")));
147+
133148
/* Convert list of names to a name and namespace */
134149
typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName);
135150

151+
#ifdef NOT_USED
152+
/* XXX this is unnecessary given the superuser check above */
136153
/* Check we have creation rights in target namespace */
137154
aclresult = pg_namespace_aclcheck(typeNamespace, GetUserId(), ACL_CREATE);
138155
if (aclresult != ACLCHECK_OK)
139156
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
140157
get_namespace_name(typeNamespace));
158+
#endif
141159

142160
/*
143161
* Look to see if type already exists (presumably as a shell; if not,
@@ -398,6 +416,8 @@ DefineType(List *names, List *parameters)
398416
* don't have a way to make the type go away if the grant option is
399417
* revoked, so ownership seems better.
400418
*/
419+
#ifdef NOT_USED
420+
/* XXX this is unnecessary given the superuser check above */
401421
if (inputOid && !pg_proc_ownercheck(inputOid, GetUserId()))
402422
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
403423
NameListToString(inputName));
@@ -419,6 +439,7 @@ DefineType(List *names, List *parameters)
419439
if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId()))
420440
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
421441
NameListToString(analyzeName));
442+
#endif
422443

423444
/* Preassign array type OID so we can insert it in pg_type.typarray */
424445
pg_type = heap_open(TypeRelationId, AccessShareLock);

0 commit comments

Comments
 (0)