From 0ceb620b17b197b1effa96a46e35b6c03942ca7a Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 18 Dec 2019 09:52:10 +0100 Subject: [PATCH] Disallow dropping rules on system tables by default This was previously not covered by allow_system_table_mods, but now it is. The impact in practice is probably low, but this makes it consistent with most other DDL commands. --- src/backend/rewrite/rewriteRemove.c | 8 ++++++++ .../unsafe_tests/expected/alter_system_table.out | 11 ++++++++++- .../modules/unsafe_tests/sql/alter_system_table.sql | 10 +++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index c5e2aed58d..bb98b6936a 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -18,6 +18,7 @@ #include "access/htup_details.h" #include "access/sysattr.h" #include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -28,6 +29,7 @@ #include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/lsyscache.h" +#include "utils/rel.h" #include "utils/syscache.h" /* @@ -72,6 +74,12 @@ RemoveRewriteRuleById(Oid ruleOid) eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; event_relation = table_open(eventRelationOid, AccessExclusiveLock); + if (!allowSystemTableMods && IsSystemRelation(event_relation)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied: \"%s\" is a system catalog", + RelationGetRelationName(event_relation)))); + /* * Now delete the pg_rewrite tuple for the rule */ diff --git a/src/test/modules/unsafe_tests/expected/alter_system_table.out b/src/test/modules/unsafe_tests/expected/alter_system_table.out index ca7eabe9bb..ecd1505cdc 100644 --- a/src/test/modules/unsafe_tests/expected/alter_system_table.out +++ b/src/test/modules/unsafe_tests/expected/alter_system_table.out @@ -81,7 +81,16 @@ CREATE RULE r1 AS ON INSERT TO pg_description DO INSTEAD NOTHING; ERROR: permission denied: "pg_description" is a system catalog ALTER RULE r1 ON pg_description RENAME TO r2; ERROR: permission denied: "pg_description" is a system catalog ---DROP RULE r2 ON pg_description; +-- now make one to test dropping: +SET allow_system_table_mods TO on; +CREATE RULE r2 AS ON INSERT TO pg_description DO INSTEAD NOTHING; +RESET allow_system_table_mods; +DROP RULE r2 ON pg_description; +ERROR: permission denied: "pg_description" is a system catalog +-- cleanup: +SET allow_system_table_mods TO on; +DROP RULE r2 ON pg_description; +RESET allow_system_table_mods; SET allow_system_table_mods = on; -- create new table in pg_catalog BEGIN; diff --git a/src/test/modules/unsafe_tests/sql/alter_system_table.sql b/src/test/modules/unsafe_tests/sql/alter_system_table.sql index 44cb3c7148..5663570d31 100644 --- a/src/test/modules/unsafe_tests/sql/alter_system_table.sql +++ b/src/test/modules/unsafe_tests/sql/alter_system_table.sql @@ -79,7 +79,15 @@ CREATE TRIGGER t1 BEFORE INSERT ON pg_description EXECUTE FUNCTION tf1(); -- rules CREATE RULE r1 AS ON INSERT TO pg_description DO INSTEAD NOTHING; ALTER RULE r1 ON pg_description RENAME TO r2; ---DROP RULE r2 ON pg_description; +-- now make one to test dropping: +SET allow_system_table_mods TO on; +CREATE RULE r2 AS ON INSERT TO pg_description DO INSTEAD NOTHING; +RESET allow_system_table_mods; +DROP RULE r2 ON pg_description; +-- cleanup: +SET allow_system_table_mods TO on; +DROP RULE r2 ON pg_description; +RESET allow_system_table_mods; SET allow_system_table_mods = on; -- 2.24.1