This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 0f2c1c498f997f8df629cc6490fbc9ac79145103
Author: Nathan Bossart <[email protected]>
AuthorDate: Mon Aug 10 06:38:24 2026 -0700

    Check for USAGE privilege on the subtype in CREATE TYPE AS RANGE.
    
    This omission allowed roles without USAGE on a type to create range
    types that depend on it, which could prevent the owner from
    changing the type later.
    
    Reported-by: Jingzhou Fu <[email protected]>
    Author: Nathan Bossart <[email protected]>
    Reviewed-by: Noah Misch <[email protected]>
    Reviewed-by: Robert Haas <[email protected]>
    Security: CVE-2026-6470
    Backpatch-through: 14
---
 doc/src/sgml/ref/create_type.sgml        |  5 +++++
 src/backend/commands/typecmds.c          |  4 ++++
 src/test/regress/expected/rangetypes.out | 15 +++++++++++++++
 src/test/regress/sql/rangetypes.sql      | 14 ++++++++++++++
 4 files changed, 38 insertions(+)

diff --git a/doc/src/sgml/ref/create_type.sgml 
b/doc/src/sgml/ref/create_type.sgml
index ac089f44bc3..ca3b8a85014 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -189,6 +189,11 @@ CREATE TYPE <replaceable 
class="parameter">name</replaceable>
     type name.  Otherwise, the multirange type name is formed by appending a
     <literal>_multirange</literal> suffix to the range type name.
    </para>
+
+   <para>
+    To be able to create a range type, you must have <literal>USAGE</literal>
+    privilege on the subtype.
+   </para>
   </refsect2>
 
   <refsect2>
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 5b3a11519cf..81f2d71698e 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1582,6 +1582,10 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
                                 errmsg("range subtype cannot be %s",
                                                format_type_be(rangeSubtype))));
 
+       aclresult = object_aclcheck(TypeRelationId, rangeSubtype, GetUserId(), 
ACL_USAGE);
+       if (aclresult != ACLCHECK_OK)
+               aclcheck_error_type(aclresult, rangeSubtype);
+
        /* Identify subopclass */
        rangeSubOpclass = findRangeSubOpclass(rangeSubOpclassName, 
rangeSubtype);
 
diff --git a/src/test/regress/expected/rangetypes.out 
b/src/test/regress/expected/rangetypes.out
index 0833e0da736..06f132fede1 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1556,6 +1556,21 @@ ERROR:  range lower bound must be less than or equal to 
range upper bound
 LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':...
                ^
 set timezone to default;
+-- CREATE TYPE AS RANGE checks for USAGE on subtype
+CREATE ROLE regress_subtype;
+CREATE TYPE mytype AS (a INT, b INT);
+REVOKE USAGE ON TYPE mytype FROM PUBLIC;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+ERROR:  permission denied for type mytype
+RESET ROLE;
+GRANT USAGE ON TYPE mytype TO regress_subtype;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+DROP TYPE mytype CASCADE;
+NOTICE:  drop cascades to type myrange
+DROP ROLE regress_subtype;
 --
 -- Test user-defined range of floats
 -- (type float8range was already made in test_setup.sql)
diff --git a/src/test/regress/sql/rangetypes.sql 
b/src/test/regress/sql/rangetypes.sql
index 2fc7dcea7e4..d66f18be5a8 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -435,6 +435,20 @@ select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 
-08)'::tstzrange;
 select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange;
 set timezone to default;
 
+-- CREATE TYPE AS RANGE checks for USAGE on subtype
+CREATE ROLE regress_subtype;
+CREATE TYPE mytype AS (a INT, b INT);
+REVOKE USAGE ON TYPE mytype FROM PUBLIC;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+GRANT USAGE ON TYPE mytype TO regress_subtype;
+SET ROLE regress_subtype;
+CREATE TYPE myrange AS RANGE (subtype = mytype);
+RESET ROLE;
+DROP TYPE mytype CASCADE;
+DROP ROLE regress_subtype;
+
 --
 -- Test user-defined range of floats
 -- (type float8range was already made in test_setup.sql)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to