]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Check CREATE privilege on multirange type schema in CREATE TYPE.
authorNathan Bossart <nathan@postgresql.org>
Mon, 11 May 2026 12:13:51 +0000 (05:13 -0700)
committerNoah Misch <noah@leadboat.com>
Mon, 11 May 2026 12:13:51 +0000 (05:13 -0700)
This omission allowed roles to create multirange types in any
schema, potentially leading to privilege escalations.  Note that
when a multirange type name is not specified in CREATE TYPE, it is
automatically placed in the range type's schema, which is checked
at the beginning of DefineRange().

Reported-by: Jelte Fennema-Nio <postgres@jeltef.nl>
Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Security: CVE-2026-6472
Backpatch-through: 14

src/backend/commands/typecmds.c
src/test/regress/expected/multirangetypes.out
src/test/regress/sql/multirangetypes.sql

index ce8c1badb39e4e7add393dbf43a0e8d9c58904dd..d8fd3e3eb7d0022afbf22d63eb9629cbde758b51 100644 (file)
@@ -1458,6 +1458,13 @@ DefineRange(CreateRangeStmt *stmt)
                        /* we can look up the subtype name immediately */
                        multirangeNamespace = QualifiedNameGetCreationNamespace(defGetQualifiedName(defel),
                                                                                                                                        &multirangeTypeName);
+
+                       /* Check we have creation rights in target namespace */
+                       aclresult = pg_namespace_aclcheck(multirangeNamespace,
+                                                                                         GetUserId(), ACL_CREATE);
+                       if (aclresult != ACLCHECK_OK)
+                               aclcheck_error(aclresult, OBJECT_SCHEMA,
+                                                          get_namespace_name(multirangeNamespace));
                }
                else
                        ereport(ERROR,
index 1d2d832ce2b206424aaf9e2896242df8578cc368..a2dbcb8ac77a2f6769bda39005ab5cd021d52460 100644 (file)
@@ -2984,6 +2984,22 @@ select _textrange1(textrange2('a','z')) @> 'b'::text;
 drop type textrange1;
 drop type textrange2;
 --
+-- CREATE TYPE checks for CREATE on multirange schema
+--
+create role regress_mr;
+create schema mr_sch;
+set role regress_mr;
+create type mytype as range (subtype=int4, multirange_type_name=mr_sch.mr_type);
+ERROR:  permission denied for schema mr_sch
+reset role;
+grant create on schema mr_sch to regress_mr;
+set role regress_mr;
+create type mytype as range (subtype=int4, multirange_type_name=mr_sch.mr_type);
+reset role;
+drop type mytype;
+drop schema mr_sch;
+drop role regress_mr;
+--
 -- Test polymorphic type system
 --
 create function anyarray_anymultirange_func(a anyarray, r anymultirange)
index ea54f290bde8502b0cc60b73d2b9bc786a9c8796..fc5e1051b4b01f80ae9ebe3dd3132f0f1c4cad3a 100644 (file)
@@ -672,6 +672,22 @@ select _textrange1(textrange2('a','z')) @> 'b'::text;
 drop type textrange1;
 drop type textrange2;
 
+--
+-- CREATE TYPE checks for CREATE on multirange schema
+--
+create role regress_mr;
+create schema mr_sch;
+set role regress_mr;
+create type mytype as range (subtype=int4, multirange_type_name=mr_sch.mr_type);
+reset role;
+grant create on schema mr_sch to regress_mr;
+set role regress_mr;
+create type mytype as range (subtype=int4, multirange_type_name=mr_sch.mr_type);
+reset role;
+drop type mytype;
+drop schema mr_sch;
+drop role regress_mr;
+
 --
 -- Test polymorphic type system
 --