diff options
Diffstat (limited to 'meta-oe/recipes-dbs')
-rw-r--r-- | meta-oe/recipes-dbs/mysql/mariadb-native_10.4.28.bb (renamed from meta-oe/recipes-dbs/mysql/mariadb-native_10.4.25.bb) | 0 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/mysql/mariadb.inc | 3 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/mysql/mariadb/CVE-2022-47015.patch | 269 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/mysql/mariadb_10.4.28.bb (renamed from meta-oe/recipes-dbs/mysql/mariadb_10.4.25.bb) | 0 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/0001-Add-support-for-RISC-V.patch | 13 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/0001-Improve-reproducibility.patch | 13 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/CVE-2022-1552.patch | 947 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch | 904 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/not-check-libperl.patch | 13 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/remove_duplicate.patch | 38 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/postgresql_12.18.bb | 11 | ||||
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb | 14 |
12 files changed, 297 insertions, 1928 deletions
diff --git a/meta-oe/recipes-dbs/mysql/mariadb-native_10.4.25.bb b/meta-oe/recipes-dbs/mysql/mariadb-native_10.4.28.bb index e1a038dfa3..e1a038dfa3 100644 --- a/meta-oe/recipes-dbs/mysql/mariadb-native_10.4.25.bb +++ b/meta-oe/recipes-dbs/mysql/mariadb-native_10.4.28.bb diff --git a/meta-oe/recipes-dbs/mysql/mariadb.inc b/meta-oe/recipes-dbs/mysql/mariadb.inc index 565f4d5613..e4eb48492a 100644 --- a/meta-oe/recipes-dbs/mysql/mariadb.inc +++ b/meta-oe/recipes-dbs/mysql/mariadb.inc @@ -16,9 +16,10 @@ SRC_URI = "https://downloads.mariadb.org/interstitial/${BP}/source/${BP}.tar.gz file://sql-CMakeLists.txt-fix-gen_lex_hash-not-found.patch \ file://0001-disable-ucontext-on-musl.patch \ file://fix-arm-atomic.patch \ + file://CVE-2022-47015.patch \ " -SRC_URI[sha256sum] = "ff963c4e11bc06b775f66f2b1ddef184996208fb4b23cfdb50d95fb02eaa7ef8" +SRC_URI[sha256sum] = "003fd23f3c6ee516176e1b62b0b43cdb6cdd3dcd4e30f855c1c5ab2baaf5a86c" UPSTREAM_CHECK_URI = "https://github.com/MariaDB/server/releases" diff --git a/meta-oe/recipes-dbs/mysql/mariadb/CVE-2022-47015.patch b/meta-oe/recipes-dbs/mysql/mariadb/CVE-2022-47015.patch new file mode 100644 index 0000000000..0ddcdc028c --- /dev/null +++ b/meta-oe/recipes-dbs/mysql/mariadb/CVE-2022-47015.patch @@ -0,0 +1,269 @@ +From be0a46b3d52b58956fd0d47d040b9f4514406954 Mon Sep 17 00:00:00 2001 +From: Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> +Date: Tue, 27 Sep 2022 15:22:57 +0900 +Subject: [PATCH] MDEV-29644 a potential bug of null pointer dereference in + spider_db_mbase::print_warnings() + +Upstream-Status: Backport [https://github.com/MariaDB/server/commit/be0a46b3d52b58956fd0d47d040b9f4514406954] +CVE: CVE-2022-47015 +Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com> +--- + .../spider/bugfix/r/mdev_29644.result | 44 ++++++++++ + .../mysql-test/spider/bugfix/t/mdev_29644.cnf | 3 + + .../spider/bugfix/t/mdev_29644.test | 58 ++++++++++++ + storage/spider/spd_db_mysql.cc | 88 ++++++++----------- + storage/spider/spd_db_mysql.h | 4 +- + 5 files changed, 141 insertions(+), 56 deletions(-) + create mode 100644 spider/mysql-test/spider/bugfix/r/mdev_29644.result + create mode 100644 spider/mysql-test/spider/bugfix/t/mdev_29644.cnf + create mode 100644 spider/mysql-test/spider/bugfix/t/mdev_29644.test + +diff --git a/spider/mysql-test/spider/bugfix/r/mdev_29644.result b/spider/mysql-test/spider/bugfix/r/mdev_29644.result +new file mode 100644 +index 00000000..eb725602 +--- /dev/null ++++ b/spider/mysql-test/spider/bugfix/r/mdev_29644.result +@@ -0,0 +1,44 @@ ++# ++# MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() ++# ++for master_1 ++for child2 ++child2_1 ++child2_2 ++child2_3 ++for child3 ++connection child2_1; ++CREATE DATABASE auto_test_remote; ++USE auto_test_remote; ++CREATE TABLE tbl_a ( ++a CHAR(5) ++) ENGINE=InnoDB DEFAULT CHARSET=utf8; ++set @orig_sql_mode=@@global.sql_mode; ++SET GLOBAL sql_mode=''; ++connection master_1; ++CREATE DATABASE auto_test_local; ++USE auto_test_local; ++CREATE TABLE tbl_a ( ++a CHAR(255) ++) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; ++SET @orig_sql_mode=@@global.sql_mode; ++SET GLOBAL sql_mode=''; ++INSERT INTO tbl_a VALUES ("this will be truncated"); ++NOT FOUND /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err ++SET @orig_log_result_errors=@@global.spider_log_result_errors; ++SET GLOBAL spider_log_result_errors=4; ++INSERT INTO tbl_a VALUES ("this will be truncated"); ++FOUND 1 /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err ++connection master_1; ++SET GLOBAL spider_log_result_errors=@orig_log_result_errors; ++SET GLOBAL sql_mode=@orig_sql_mode; ++DROP DATABASE IF EXISTS auto_test_local; ++connection child2_1; ++SET GLOBAL sql_mode=@orig_sql_mode; ++DROP DATABASE IF EXISTS auto_test_remote; ++for master_1 ++for child2 ++child2_1 ++child2_2 ++child2_3 ++for child3 +diff --git a/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf b/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf +new file mode 100644 +index 00000000..05dfd8a0 +--- /dev/null ++++ b/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf +@@ -0,0 +1,3 @@ ++!include include/default_mysqld.cnf ++!include ../my_1_1.cnf ++!include ../my_2_1.cnf +diff --git a/spider/mysql-test/spider/bugfix/t/mdev_29644.test b/spider/mysql-test/spider/bugfix/t/mdev_29644.test +new file mode 100644 +index 00000000..4ebdf317 +--- /dev/null ++++ b/spider/mysql-test/spider/bugfix/t/mdev_29644.test +@@ -0,0 +1,58 @@ ++--echo # ++--echo # MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() ++--echo # ++ ++# The test case below does not cause the potential null pointer dereference. ++# It is just for checking spider_db_mbase::fetch_and_print_warnings() works. ++ ++--disable_query_log ++--disable_result_log ++--source ../../t/test_init.inc ++--enable_result_log ++--enable_query_log ++ ++--connection child2_1 ++CREATE DATABASE auto_test_remote; ++USE auto_test_remote; ++eval CREATE TABLE tbl_a ( ++ a CHAR(5) ++) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; ++set @orig_sql_mode=@@global.sql_mode; ++SET GLOBAL sql_mode=''; ++ ++--connection master_1 ++CREATE DATABASE auto_test_local; ++USE auto_test_local; ++eval CREATE TABLE tbl_a ( ++ a CHAR(255) ++) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; ++ ++SET @orig_sql_mode=@@global.sql_mode; ++SET GLOBAL sql_mode=''; ++ ++let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.1.err; ++let SEARCH_PATTERN= \[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*; ++ ++INSERT INTO tbl_a VALUES ("this will be truncated"); ++--source include/search_pattern_in_file.inc # should not find ++ ++SET @orig_log_result_errors=@@global.spider_log_result_errors; ++SET GLOBAL spider_log_result_errors=4; ++ ++INSERT INTO tbl_a VALUES ("this will be truncated"); ++--source include/search_pattern_in_file.inc # should find ++ ++--connection master_1 ++SET GLOBAL spider_log_result_errors=@orig_log_result_errors; ++SET GLOBAL sql_mode=@orig_sql_mode; ++DROP DATABASE IF EXISTS auto_test_local; ++ ++--connection child2_1 ++SET GLOBAL sql_mode=@orig_sql_mode; ++DROP DATABASE IF EXISTS auto_test_remote; ++ ++--disable_query_log ++--disable_result_log ++--source ../t/test_deinit.inc ++--enable_query_log ++--enable_result_log +diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc +index 85f910aa..7d6bd599 100644 +--- a/storage/spider/spd_db_mysql.cc ++++ b/storage/spider/spd_db_mysql.cc +@@ -2197,7 +2197,7 @@ int spider_db_mbase::exec_query( + db_conn->affected_rows, db_conn->insert_id, + db_conn->server_status, db_conn->warning_count); + if (spider_param_log_result_errors() >= 3) +- print_warnings(l_time); ++ fetch_and_print_warnings(l_time); + } else if (log_result_errors >= 4) + { + time_t cur_time = (time_t) time((time_t*) 0); +@@ -2279,61 +2279,43 @@ bool spider_db_mbase::is_xa_nota_error( + DBUG_RETURN(xa_nota); + } + +-void spider_db_mbase::print_warnings( +- struct tm *l_time +-) { +- DBUG_ENTER("spider_db_mbase::print_warnings"); +- DBUG_PRINT("info",("spider this=%p", this)); +- if (db_conn->status == MYSQL_STATUS_READY) ++void spider_db_mbase::fetch_and_print_warnings(struct tm *l_time) ++{ ++ DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings"); ++ ++ if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY || ++ db_conn->server_status & SERVER_MORE_RESULTS_EXISTS) ++ DBUG_VOID_RETURN; ++ ++ if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, ++ SPIDER_SQL_SHOW_WARNINGS_LEN)) ++ DBUG_VOID_RETURN; ++ ++ MYSQL_RES *res= mysql_store_result(db_conn); ++ if (!res) ++ DBUG_VOID_RETURN; ++ ++ uint num_fields= mysql_num_fields(res); ++ if (num_fields != 3) + { +-#if MYSQL_VERSION_ID < 50500 +- if (!(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)) +-#else +- if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS)) +-#endif +- { +- if ( +- spider_param_dry_access() || +- !mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, +- SPIDER_SQL_SHOW_WARNINGS_LEN) +- ) { +- MYSQL_RES *res = NULL; +- MYSQL_ROW row = NULL; +- uint num_fields; +- if ( +- spider_param_dry_access() || +- !(res = mysql_store_result(db_conn)) || +- !(row = mysql_fetch_row(res)) +- ) { +- if (mysql_errno(db_conn)) +- { +- if (res) +- mysql_free_result(res); +- DBUG_VOID_RETURN; +- } +- /* no record is ok */ +- } +- num_fields = mysql_num_fields(res); +- if (num_fields != 3) +- { +- mysql_free_result(res); +- DBUG_VOID_RETURN; +- } +- while (row) +- { +- fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] " +- "from [%s] %ld to %ld: %s %s %s\n", ++ mysql_free_result(res); ++ DBUG_VOID_RETURN; ++ } ++ ++ MYSQL_ROW row= mysql_fetch_row(res); ++ while (row) ++ { ++ fprintf(stderr, ++ "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld " ++ "to %ld: %s %s %s\n", + l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, +- l_time->tm_hour, l_time->tm_min, l_time->tm_sec, +- conn->tgt_host, (ulong) db_conn->thread_id, +- (ulong) current_thd->thread_id, row[0], row[1], row[2]); +- row = mysql_fetch_row(res); +- } +- if (res) +- mysql_free_result(res); +- } +- } ++ l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host, ++ (ulong) db_conn->thread_id, (ulong) current_thd->thread_id, row[0], ++ row[1], row[2]); ++ row= mysql_fetch_row(res); + } ++ mysql_free_result(res); ++ + DBUG_VOID_RETURN; + } + +diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h +index 626bb4d5..82c7c0ec 100644 +--- a/storage/spider/spd_db_mysql.h ++++ b/storage/spider/spd_db_mysql.h +@@ -439,9 +439,7 @@ class spider_db_mbase: public spider_db_conn + bool is_xa_nota_error( + int error_num + ); +- void print_warnings( +- struct tm *l_time +- ); ++ void fetch_and_print_warnings(struct tm *l_time); + spider_db_result *store_result( + spider_db_result_buffer **spider_res_buf, + st_spider_db_request_key *request_key, +-- +2.25.1 diff --git a/meta-oe/recipes-dbs/mysql/mariadb_10.4.25.bb b/meta-oe/recipes-dbs/mysql/mariadb_10.4.28.bb index c0b53379d9..c0b53379d9 100644 --- a/meta-oe/recipes-dbs/mysql/mariadb_10.4.25.bb +++ b/meta-oe/recipes-dbs/mysql/mariadb_10.4.28.bb diff --git a/meta-oe/recipes-dbs/postgresql/files/0001-Add-support-for-RISC-V.patch b/meta-oe/recipes-dbs/postgresql/files/0001-Add-support-for-RISC-V.patch index a1f5b2a7b4..e5fb85170b 100644 --- a/meta-oe/recipes-dbs/postgresql/files/0001-Add-support-for-RISC-V.patch +++ b/meta-oe/recipes-dbs/postgresql/files/0001-Add-support-for-RISC-V.patch @@ -9,10 +9,10 @@ extending the existing aarch64 macro works. src/include/storage/s_lock.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h -index 3fe29ce..7cd578f 100644 ---- a/src/include/storage/s_lock.h -+++ b/src/include/storage/s_lock.h +Index: postgresql-12.16/src/include/storage/s_lock.h +=================================================================== +--- postgresql-12.16.orig/src/include/storage/s_lock.h ++++ postgresql-12.16/src/include/storage/s_lock.h @@ -317,11 +317,12 @@ tas(volatile slock_t *lock) /* @@ -35,7 +35,4 @@ index 3fe29ce..7cd578f 100644 +#endif /* __arm__ || __arm || __aarch64__ || __aarch64 || __riscv */ - /* --- -2.9.3 - + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ diff --git a/meta-oe/recipes-dbs/postgresql/files/0001-Improve-reproducibility.patch b/meta-oe/recipes-dbs/postgresql/files/0001-Improve-reproducibility.patch index 32b7f42845..70c813adf5 100644 --- a/meta-oe/recipes-dbs/postgresql/files/0001-Improve-reproducibility.patch +++ b/meta-oe/recipes-dbs/postgresql/files/0001-Improve-reproducibility.patch @@ -19,11 +19,11 @@ Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> src/common/Makefile | 4 ---- 1 file changed, 4 deletions(-) -diff --git a/src/common/Makefile b/src/common/Makefile -index 1fc2c66..5e6c457 100644 ---- a/src/common/Makefile -+++ b/src/common/Makefile -@@ -27,10 +27,6 @@ include $(top_builddir)/src/Makefile.global +Index: postgresql-12.16/src/common/Makefile +=================================================================== +--- postgresql-12.16.orig/src/common/Makefile ++++ postgresql-12.16/src/common/Makefile +@@ -31,10 +31,6 @@ include $(top_builddir)/src/Makefile.glo # don't include subdirectory-path-dependent -I and -L switches STD_CPPFLAGS := $(filter-out -I$(top_srcdir)/src/include -I$(top_builddir)/src/include,$(CPPFLAGS)) STD_LDFLAGS := $(filter-out -L$(top_builddir)/src/common -L$(top_builddir)/src/port,$(LDFLAGS)) @@ -34,6 +34,3 @@ index 1fc2c66..5e6c457 100644 override CPPFLAGS += -DVAL_CFLAGS_SL="\"$(CFLAGS_SL)\"" override CPPFLAGS += -DVAL_LDFLAGS="\"$(STD_LDFLAGS)\"" override CPPFLAGS += -DVAL_LDFLAGS_EX="\"$(LDFLAGS_EX)\"" --- -2.7.4 - diff --git a/meta-oe/recipes-dbs/postgresql/files/CVE-2022-1552.patch b/meta-oe/recipes-dbs/postgresql/files/CVE-2022-1552.patch deleted file mode 100644 index 6f0d5ac06f..0000000000 --- a/meta-oe/recipes-dbs/postgresql/files/CVE-2022-1552.patch +++ /dev/null @@ -1,947 +0,0 @@ -From 31eefa1efc8eecb6ab91c8835d2952d44a3b1ae1 Mon Sep 17 00:00:00 2001 -From: Hitendra Prajapati <hprajapati@mvista.com> -Date: Thu, 22 Sep 2022 11:20:41 +0530 -Subject: [PATCH] CVE-2022-1552 - -Upstream-Status: Backport [https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ab49ce7c3414ac19e4afb386d7843ce2d2fb8bda && https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=677a494789062ca88e0142a17bedd5415f6ab0aa] - -CVE: CVE-2022-1552 -Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> ---- - contrib/amcheck/expected/check_btree.out | 23 ++++++ - contrib/amcheck/sql/check_btree.sql | 21 +++++ - contrib/amcheck/verify_nbtree.c | 27 +++++++ - src/backend/access/brin/brin.c | 29 ++++++- - src/backend/catalog/index.c | 65 ++++++++++++---- - src/backend/commands/cluster.c | 37 ++++++--- - src/backend/commands/indexcmds.c | 98 ++++++++++++++++++++---- - src/backend/commands/matview.c | 30 +++----- - src/backend/utils/init/miscinit.c | 24 +++--- - src/test/regress/expected/privileges.out | 71 +++++++++++++++++ - src/test/regress/sql/privileges.sql | 64 ++++++++++++++++ - 11 files changed, 422 insertions(+), 67 deletions(-) - -diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out -index 59a805d..0fd6ea0 100644 ---- a/contrib/amcheck/expected/check_btree.out -+++ b/contrib/amcheck/expected/check_btree.out -@@ -168,11 +168,34 @@ SELECT bt_index_check('toasty', true); - - (1 row) - -+-- -+-- Check that index expressions and predicates are run as the table's owner -+-- -+TRUNCATE bttest_a; -+INSERT INTO bttest_a SELECT * FROM generate_series(1, 1000); -+ALTER TABLE bttest_a OWNER TO regress_bttest_role; -+-- A dummy index function checking current_user -+CREATE FUNCTION ifun(int8) RETURNS int8 AS $$ -+BEGIN -+ ASSERT current_user = 'regress_bttest_role', -+ format('ifun(%s) called by %s', $1, current_user); -+ RETURN $1; -+END; -+$$ LANGUAGE plpgsql IMMUTABLE; -+CREATE INDEX bttest_a_expr_idx ON bttest_a ((ifun(id) + ifun(0))) -+ WHERE ifun(id + 10) > ifun(10); -+SELECT bt_index_check('bttest_a_expr_idx', true); -+ bt_index_check -+---------------- -+ -+(1 row) -+ - -- cleanup - DROP TABLE bttest_a; - DROP TABLE bttest_b; - DROP TABLE bttest_multi; - DROP TABLE delete_test_table; - DROP TABLE toast_bug; -+DROP FUNCTION ifun(int8); - DROP OWNED BY regress_bttest_role; -- permissions - DROP ROLE regress_bttest_role; -diff --git a/contrib/amcheck/sql/check_btree.sql b/contrib/amcheck/sql/check_btree.sql -index 99acbc8..3248187 100644 ---- a/contrib/amcheck/sql/check_btree.sql -+++ b/contrib/amcheck/sql/check_btree.sql -@@ -110,11 +110,32 @@ INSERT INTO toast_bug SELECT repeat('a', 2200); - -- Should not get false positive report of corruption: - SELECT bt_index_check('toasty', true); - -+-- -+-- Check that index expressions and predicates are run as the table's owner -+-- -+TRUNCATE bttest_a; -+INSERT INTO bttest_a SELECT * FROM generate_series(1, 1000); -+ALTER TABLE bttest_a OWNER TO regress_bttest_role; -+-- A dummy index function checking current_user -+CREATE FUNCTION ifun(int8) RETURNS int8 AS $$ -+BEGIN -+ ASSERT current_user = 'regress_bttest_role', -+ format('ifun(%s) called by %s', $1, current_user); -+ RETURN $1; -+END; -+$$ LANGUAGE plpgsql IMMUTABLE; -+ -+CREATE INDEX bttest_a_expr_idx ON bttest_a ((ifun(id) + ifun(0))) -+ WHERE ifun(id + 10) > ifun(10); -+ -+SELECT bt_index_check('bttest_a_expr_idx', true); -+ - -- cleanup - DROP TABLE bttest_a; - DROP TABLE bttest_b; - DROP TABLE bttest_multi; - DROP TABLE delete_test_table; - DROP TABLE toast_bug; -+DROP FUNCTION ifun(int8); - DROP OWNED BY regress_bttest_role; -- permissions - DROP ROLE regress_bttest_role; -diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c -index 700a02f..cb6475d 100644 ---- a/contrib/amcheck/verify_nbtree.c -+++ b/contrib/amcheck/verify_nbtree.c -@@ -228,6 +228,9 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, - Relation indrel; - Relation heaprel; - LOCKMODE lockmode; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - - if (parentcheck) - lockmode = ShareLock; -@@ -244,9 +247,27 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, - */ - heapid = IndexGetRelation(indrelid, true); - if (OidIsValid(heapid)) -+ { - heaprel = table_open(heapid, lockmode); -+ -+ /* -+ * Switch to the table owner's userid, so that any index functions are -+ * run as that user. Also lock down security-restricted operations -+ * and arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heaprel->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ } - else -+ { - heaprel = NULL; -+ /* for "gcc -Og" https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78394 */ -+ save_userid = InvalidOid; -+ save_sec_context = -1; -+ save_nestlevel = -1; -+ } - - /* - * Open the target index relations separately (like relation_openrv(), but -@@ -293,6 +314,12 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, - heapallindexed, rootdescend); - } - -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); -+ - /* - * Release locks early. That's ok here because nothing in the called - * routines will trigger shared cache invalidations to be sent, so we can -diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c -index c7b403b..781cac2 100644 ---- a/src/backend/access/brin/brin.c -+++ b/src/backend/access/brin/brin.c -@@ -873,6 +873,9 @@ brin_summarize_range(PG_FUNCTION_ARGS) - Oid heapoid; - Relation indexRel; - Relation heapRel; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - double numSummarized = 0; - - if (RecoveryInProgress()) -@@ -899,7 +902,22 @@ brin_summarize_range(PG_FUNCTION_ARGS) - */ - heapoid = IndexGetRelation(indexoid, true); - if (OidIsValid(heapoid)) -+ { - heapRel = table_open(heapoid, ShareUpdateExclusiveLock); -+ -+ /* -+ * Autovacuum calls us. For its benefit, switch to the table owner's -+ * userid, so that any index functions are run as that user. Also -+ * lock down security-restricted operations and arrange to make GUC -+ * variable changes local to this command. This is harmless, albeit -+ * unnecessary, when called from SQL, because we fail shortly if the -+ * user does not own the index. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heapRel->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ } - else - heapRel = NULL; - -@@ -914,7 +932,7 @@ brin_summarize_range(PG_FUNCTION_ARGS) - RelationGetRelationName(indexRel)))); - - /* User must own the index (comparable to privileges needed for VACUUM) */ -- if (!pg_class_ownercheck(indexoid, GetUserId())) -+ if (heapRel != NULL && !pg_class_ownercheck(indexoid, save_userid)) - aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, - RelationGetRelationName(indexRel)); - -@@ -932,6 +950,12 @@ brin_summarize_range(PG_FUNCTION_ARGS) - /* OK, do it */ - brinsummarize(indexRel, heapRel, heapBlk, true, &numSummarized, NULL); - -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); -+ - relation_close(indexRel, ShareUpdateExclusiveLock); - relation_close(heapRel, ShareUpdateExclusiveLock); - -@@ -973,6 +997,9 @@ brin_desummarize_range(PG_FUNCTION_ARGS) - * passed indexoid isn't an index then IndexGetRelation() will fail. - * Rather than emitting a not-very-helpful error message, postpone - * complaining, expecting that the is-it-an-index test below will fail. -+ * -+ * Unlike brin_summarize_range(), autovacuum never calls this. Hence, we -+ * don't switch userid. - */ - heapoid = IndexGetRelation(indexoid, true); - if (OidIsValid(heapoid)) -diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c -index 3ece136..0333bfd 100644 ---- a/src/backend/catalog/index.c -+++ b/src/backend/catalog/index.c -@@ -1400,6 +1400,9 @@ index_concurrently_build(Oid heapRelationId, - Oid indexRelationId) - { - Relation heapRel; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - Relation indexRelation; - IndexInfo *indexInfo; - -@@ -1409,7 +1412,16 @@ index_concurrently_build(Oid heapRelationId, - /* Open and lock the parent heap relation */ - heapRel = table_open(heapRelationId, ShareUpdateExclusiveLock); - -- /* And the target index relation */ -+ /* -+ * Switch to the table owner's userid, so that any index functions are run -+ * as that user. Also lock down security-restricted operations and -+ * arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heapRel->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ - indexRelation = index_open(indexRelationId, RowExclusiveLock); - - /* -@@ -1425,6 +1437,12 @@ index_concurrently_build(Oid heapRelationId, - /* Now build the index */ - index_build(heapRel, indexRelation, indexInfo, false, true); - -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); -+ - /* Close both the relations, but keep the locks */ - table_close(heapRel, NoLock); - index_close(indexRelation, NoLock); -@@ -3271,7 +3289,17 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) - - /* Open and lock the parent heap relation */ - heapRelation = table_open(heapId, ShareUpdateExclusiveLock); -- /* And the target index relation */ -+ -+ /* -+ * Switch to the table owner's userid, so that any index functions are run -+ * as that user. Also lock down security-restricted operations and -+ * arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heapRelation->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ - indexRelation = index_open(indexId, RowExclusiveLock); - - /* -@@ -3284,16 +3312,6 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) - /* mark build is concurrent just for consistency */ - indexInfo->ii_Concurrent = true; - -- /* -- * Switch to the table owner's userid, so that any index functions are run -- * as that user. Also lock down security-restricted operations and -- * arrange to make GUC variable changes local to this command. -- */ -- GetUserIdAndSecContext(&save_userid, &save_sec_context); -- SetUserIdAndSecContext(heapRelation->rd_rel->relowner, -- save_sec_context | SECURITY_RESTRICTED_OPERATION); -- save_nestlevel = NewGUCNestLevel(); -- - /* - * Scan the index and gather up all the TIDs into a tuplesort object. - */ -@@ -3497,6 +3515,9 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, - Relation iRel, - heapRelation; - Oid heapId; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - IndexInfo *indexInfo; - volatile bool skipped_constraint = false; - PGRUsage ru0; -@@ -3527,6 +3548,16 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, - */ - iRel = index_open(indexId, AccessExclusiveLock); - -+ /* -+ * Switch to the table owner's userid, so that any index functions are run -+ * as that user. Also lock down security-restricted operations and -+ * arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heapRelation->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ - if (progress) - pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, - iRel->rd_rel->relam); -@@ -3684,12 +3715,18 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, - errdetail_internal("%s", - pg_rusage_show(&ru0)))); - -- if (progress) -- pgstat_progress_end_command(); -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); - - /* Close rels, but keep locks */ - index_close(iRel, NoLock); - table_close(heapRelation, NoLock); -+ -+ if (progress) -+ pgstat_progress_end_command(); - } - - /* -diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c -index bd6f408..74db03e 100644 ---- a/src/backend/commands/cluster.c -+++ b/src/backend/commands/cluster.c -@@ -266,6 +266,9 @@ void - cluster_rel(Oid tableOid, Oid indexOid, int options) - { - Relation OldHeap; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - bool verbose = ((options & CLUOPT_VERBOSE) != 0); - bool recheck = ((options & CLUOPT_RECHECK) != 0); - -@@ -295,6 +298,16 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - return; - } - -+ /* -+ * Switch to the table owner's userid, so that any index functions are run -+ * as that user. Also lock down security-restricted operations and -+ * arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(OldHeap->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ - /* - * Since we may open a new transaction for each relation, we have to check - * that the relation still is what we think it is. -@@ -309,11 +322,10 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - Form_pg_index indexForm; - - /* Check that the user still owns the relation */ -- if (!pg_class_ownercheck(tableOid, GetUserId())) -+ if (!pg_class_ownercheck(tableOid, save_userid)) - { - relation_close(OldHeap, AccessExclusiveLock); -- pgstat_progress_end_command(); -- return; -+ goto out; - } - - /* -@@ -327,8 +339,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - if (RELATION_IS_OTHER_TEMP(OldHeap)) - { - relation_close(OldHeap, AccessExclusiveLock); -- pgstat_progress_end_command(); -- return; -+ goto out; - } - - if (OidIsValid(indexOid)) -@@ -339,8 +350,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(indexOid))) - { - relation_close(OldHeap, AccessExclusiveLock); -- pgstat_progress_end_command(); -- return; -+ goto out; - } - - /* -@@ -350,8 +360,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - if (!HeapTupleIsValid(tuple)) /* probably can't happen */ - { - relation_close(OldHeap, AccessExclusiveLock); -- pgstat_progress_end_command(); -- return; -+ goto out; - } - indexForm = (Form_pg_index) GETSTRUCT(tuple); - if (!indexForm->indisclustered) -@@ -413,8 +422,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - !RelationIsPopulated(OldHeap)) - { - relation_close(OldHeap, AccessExclusiveLock); -- pgstat_progress_end_command(); -- return; -+ goto out; - } - - /* -@@ -430,6 +438,13 @@ cluster_rel(Oid tableOid, Oid indexOid, int options) - - /* NB: rebuild_relation does table_close() on OldHeap */ - -+out: -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); -+ - pgstat_progress_end_command(); - } - -diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c -index be1cf8c..167b377 100644 ---- a/src/backend/commands/indexcmds.c -+++ b/src/backend/commands/indexcmds.c -@@ -470,21 +470,22 @@ DefineIndex(Oid relationId, - LOCKTAG heaplocktag; - LOCKMODE lockmode; - Snapshot snapshot; -- int save_nestlevel = -1; -+ Oid root_save_userid; -+ int root_save_sec_context; -+ int root_save_nestlevel; - int i; - -+ root_save_nestlevel = NewGUCNestLevel(); -+ - /* - * Some callers need us to run with an empty default_tablespace; this is a - * necessary hack to be able to reproduce catalog state accurately when - * recreating indexes after table-rewriting ALTER TABLE. - */ - if (stmt->reset_default_tblspc) -- { -- save_nestlevel = NewGUCNestLevel(); - (void) set_config_option("default_tablespace", "", - PGC_USERSET, PGC_S_SESSION, - GUC_ACTION_SAVE, true, 0, false); -- } - - /* - * Force non-concurrent build on temporary relations, even if CONCURRENTLY -@@ -563,6 +564,15 @@ DefineIndex(Oid relationId, - lockmode = concurrent ? ShareUpdateExclusiveLock : ShareLock; - rel = table_open(relationId, lockmode); - -+ /* -+ * Switch to the table owner's userid, so that any index functions are run -+ * as that user. Also lock down security-restricted operations. We -+ * already arranged to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&root_save_userid, &root_save_sec_context); -+ SetUserIdAndSecContext(rel->rd_rel->relowner, -+ root_save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ - namespaceId = RelationGetNamespace(rel); - - /* Ensure that it makes sense to index this kind of relation */ -@@ -648,7 +658,7 @@ DefineIndex(Oid relationId, - { - AclResult aclresult; - -- aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), -+ aclresult = pg_namespace_aclcheck(namespaceId, root_save_userid, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, OBJECT_SCHEMA, -@@ -680,7 +690,7 @@ DefineIndex(Oid relationId, - { - AclResult aclresult; - -- aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), -+ aclresult = pg_tablespace_aclcheck(tablespaceId, root_save_userid, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, OBJECT_TABLESPACE, -@@ -1066,15 +1076,17 @@ DefineIndex(Oid relationId, - - ObjectAddressSet(address, RelationRelationId, indexRelationId); - -- /* -- * Revert to original default_tablespace. Must do this before any return -- * from this function, but after index_create, so this is a good time. -- */ -- if (save_nestlevel >= 0) -- AtEOXact_GUC(true, save_nestlevel); -- - if (!OidIsValid(indexRelationId)) - { -+ /* -+ * Roll back any GUC changes executed by index functions. Also revert -+ * to original default_tablespace if we changed it above. -+ */ -+ AtEOXact_GUC(false, root_save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(root_save_userid, root_save_sec_context); -+ - table_close(rel, NoLock); - - /* If this is the top-level index, we're done */ -@@ -1084,6 +1096,17 @@ DefineIndex(Oid relationId, - return address; - } - -+ /* -+ * Roll back any GUC changes executed by index functions, and keep -+ * subsequent changes local to this command. It's barely possible that -+ * some index function changed a behavior-affecting GUC, e.g. xmloption, -+ * that affects subsequent steps. This improves bug-compatibility with -+ * older PostgreSQL versions. They did the AtEOXact_GUC() here for the -+ * purpose of clearing the above default_tablespace change. -+ */ -+ AtEOXact_GUC(false, root_save_nestlevel); -+ root_save_nestlevel = NewGUCNestLevel(); -+ - /* Add any requested comment */ - if (stmt->idxcomment != NULL) - CreateComments(indexRelationId, RelationRelationId, 0, -@@ -1130,6 +1153,9 @@ DefineIndex(Oid relationId, - { - Oid childRelid = part_oids[i]; - Relation childrel; -+ Oid child_save_userid; -+ int child_save_sec_context; -+ int child_save_nestlevel; - List *childidxs; - ListCell *cell; - AttrNumber *attmap; -@@ -1138,6 +1164,12 @@ DefineIndex(Oid relationId, - - childrel = table_open(childRelid, lockmode); - -+ GetUserIdAndSecContext(&child_save_userid, -+ &child_save_sec_context); -+ SetUserIdAndSecContext(childrel->rd_rel->relowner, -+ child_save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ child_save_nestlevel = NewGUCNestLevel(); -+ - /* - * Don't try to create indexes on foreign tables, though. Skip - * those if a regular index, or fail if trying to create a -@@ -1153,6 +1185,9 @@ DefineIndex(Oid relationId, - errdetail("Table \"%s\" contains partitions that are foreign tables.", - RelationGetRelationName(rel)))); - -+ AtEOXact_GUC(false, child_save_nestlevel); -+ SetUserIdAndSecContext(child_save_userid, -+ child_save_sec_context); - table_close(childrel, lockmode); - continue; - } -@@ -1226,6 +1261,9 @@ DefineIndex(Oid relationId, - } - - list_free(childidxs); -+ AtEOXact_GUC(false, child_save_nestlevel); -+ SetUserIdAndSecContext(child_save_userid, -+ child_save_sec_context); - table_close(childrel, NoLock); - - /* -@@ -1280,12 +1318,21 @@ DefineIndex(Oid relationId, - if (found_whole_row) - elog(ERROR, "cannot convert whole-row table reference"); - -+ /* -+ * Recurse as the starting user ID. Callee will use that -+ * for permission checks, then switch again. -+ */ -+ Assert(GetUserId() == child_save_userid); -+ SetUserIdAndSecContext(root_save_userid, -+ root_save_sec_context); - DefineIndex(childRelid, childStmt, - InvalidOid, /* no predefined OID */ - indexRelationId, /* this is our child */ - createdConstraintId, - is_alter_table, check_rights, check_not_in_use, - skip_build, quiet); -+ SetUserIdAndSecContext(child_save_userid, -+ child_save_sec_context); - } - - pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, -@@ -1322,12 +1369,17 @@ DefineIndex(Oid relationId, - * Indexes on partitioned tables are not themselves built, so we're - * done here. - */ -+ AtEOXact_GUC(false, root_save_nestlevel); -+ SetUserIdAndSecContext(root_save_userid, root_save_sec_context); - table_close(rel, NoLock); - if (!OidIsValid(parentIndexId)) - pgstat_progress_end_command(); - return address; - } - -+ AtEOXact_GUC(false, root_save_nestlevel); -+ SetUserIdAndSecContext(root_save_userid, root_save_sec_context); -+ - if (!concurrent) - { - /* Close the heap and we're done, in the non-concurrent case */ -@@ -3040,6 +3092,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) - Oid newIndexId; - Relation indexRel; - Relation heapRel; -+ Oid save_userid; -+ int save_sec_context; -+ int save_nestlevel; - Relation newIndexRel; - LockRelId *lockrelid; - -@@ -3047,6 +3102,16 @@ ReindexRelationConcurrently(Oid relationOid, int options) - heapRel = table_open(indexRel->rd_index->indrelid, - ShareUpdateExclusiveLock); - -+ /* -+ * Switch to the table owner's userid, so that any index functions are -+ * run as that user. Also lock down security-restricted operations -+ * and arrange to make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(heapRel->rd_rel->relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); -+ - /* This function shouldn't be called for temporary relations. */ - if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) - elog(ERROR, "cannot reindex a temporary table concurrently"); -@@ -3101,6 +3166,13 @@ ReindexRelationConcurrently(Oid relationOid, int options) - - index_close(indexRel, NoLock); - index_close(newIndexRel, NoLock); -+ -+ /* Roll back any GUC changes executed by index functions */ -+ AtEOXact_GUC(false, save_nestlevel); -+ -+ /* Restore userid and security context */ -+ SetUserIdAndSecContext(save_userid, save_sec_context); -+ - table_close(heapRel, NoLock); - } - -diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c -index 80e9ec0..e485661 100644 ---- a/src/backend/commands/matview.c -+++ b/src/backend/commands/matview.c -@@ -167,6 +167,17 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, - lockmode, 0, - RangeVarCallbackOwnsTable, NULL); - matviewRel = table_open(matviewOid, NoLock); -+ relowner = matviewRel->rd_rel->relowner; -+ -+ /* -+ * Switch to the owner's userid, so that any functions are run as that -+ * user. Also lock down security-restricted operations and arrange to -+ * make GUC variable changes local to this command. -+ */ -+ GetUserIdAndSecContext(&save_userid, &save_sec_context); -+ SetUserIdAndSecContext(relowner, -+ save_sec_context | SECURITY_RESTRICTED_OPERATION); -+ save_nestlevel = NewGUCNestLevel(); - - /* Make sure it is a materialized view. */ - if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW) -@@ -268,19 +279,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, - */ - SetMatViewPopulatedState(matviewRel, !stmt->skipData); - -- relowner = matviewRel->rd_rel->relowner; -- -- /* -- * Switch to the owner's userid, so that any functions are run as that -- * user. Also arrange to make GUC variable changes local to this command. -- * Don't lock it down too tight to create a temporary table just yet. We -- * will switch modes when we are about to execute user code. -- */ -- GetUserIdAndSecContext(&save_userid, &save_sec_context); -- SetUserIdAndSecContext(relowner, -- save_sec_context | SECURITY_LOCAL_USERID_CHANGE); -- save_nestlevel = NewGUCNestLevel(); -- - /* Concurrent refresh builds new data in temp tablespace, and does diff. */ - if (concurrent) - { -@@ -303,12 +301,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, - LockRelationOid(OIDNewHeap, AccessExclusiveLock); - dest = CreateTransientRelDestReceiver(OIDNewHeap); - -- /* -- * Now lock down security-restricted operations. -- */ -- SetUserIdAndSecContext(relowner, -- save_sec_context | SECURITY_RESTRICTED_OPERATION); -- - /* Generate the data, if wanted. */ - if (!stmt->skipData) - processed = refresh_matview_datafill(dest, dataQuery, queryString); -diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c -index de554e2..c9f858e 100644 ---- a/src/backend/utils/init/miscinit.c -+++ b/src/backend/utils/init/miscinit.c -@@ -455,15 +455,21 @@ GetAuthenticatedUserId(void) - * with guc.c's internal state, so SET ROLE has to be disallowed. - * - * SECURITY_RESTRICTED_OPERATION indicates that we are inside an operation -- * that does not wish to trust called user-defined functions at all. This -- * bit prevents not only SET ROLE, but various other changes of session state -- * that normally is unprotected but might possibly be used to subvert the -- * calling session later. An example is replacing an existing prepared -- * statement with new code, which will then be executed with the outer -- * session's permissions when the prepared statement is next used. Since -- * these restrictions are fairly draconian, we apply them only in contexts -- * where the called functions are really supposed to be side-effect-free -- * anyway, such as VACUUM/ANALYZE/REINDEX. -+ * that does not wish to trust called user-defined functions at all. The -+ * policy is to use this before operations, e.g. autovacuum and REINDEX, that -+ * enumerate relations of a database or schema and run functions associated -+ * with each found relation. The relation owner is the new user ID. Set this -+ * as soon as possible after locking the relation. Restore the old user ID as -+ * late as possible before closing the relation; restoring it shortly after -+ * close is also tolerable. If a command has both relation-enumerating and -+ * non-enumerating modes, e.g. ANALYZE, both modes set this bit. This bit -+ * prevents not only SET ROLE, but various other changes of session state that -+ * normally is unprotected but might possibly be used to subvert the calling -+ * session later. An example is replacing an existing prepared statement with -+ * new code, which will then be executed with the outer session's permissions -+ * when the prepared statement is next used. These restrictions are fairly -+ * draconian, but the functions called in relation-enumerating operations are -+ * really supposed to be side-effect-free anyway. - * - * SECURITY_NOFORCE_RLS indicates that we are inside an operation which should - * ignore the FORCE ROW LEVEL SECURITY per-table indication. This is used to -diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out -index 186d2fb..0f0c1b3 100644 ---- a/src/test/regress/expected/privileges.out -+++ b/src/test/regress/expected/privileges.out -@@ -1336,6 +1336,61 @@ SELECT has_table_privilege('regress_priv_user1', 'atest4', 'SELECT WITH GRANT OP - -- security-restricted operations - \c - - CREATE ROLE regress_sro_user; -+-- Check that index expressions and predicates are run as the table's owner -+-- A dummy index function checking current_user -+CREATE FUNCTION sro_ifun(int) RETURNS int AS $$ -+BEGIN -+ -- Below we set the table's owner to regress_sro_user -+ ASSERT current_user = 'regress_sro_user', -+ format('sro_ifun(%s) called by %s', $1, current_user); -+ RETURN $1; -+END; -+$$ LANGUAGE plpgsql IMMUTABLE; -+-- Create a table owned by regress_sro_user -+CREATE TABLE sro_tab (a int); -+ALTER TABLE sro_tab OWNER TO regress_sro_user; -+INSERT INTO sro_tab VALUES (1), (2), (3); -+-- Create an expression index with a predicate -+CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+DROP INDEX sro_idx; -+-- Do the same concurrently -+CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+-- REINDEX -+REINDEX TABLE sro_tab; -+REINDEX INDEX sro_idx; -+REINDEX TABLE CONCURRENTLY sro_tab; -+DROP INDEX sro_idx; -+-- CLUSTER -+CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))); -+CLUSTER sro_tab USING sro_cluster_idx; -+DROP INDEX sro_cluster_idx; -+-- BRIN index -+CREATE INDEX sro_brin ON sro_tab USING brin ((sro_ifun(a) + sro_ifun(0))); -+SELECT brin_desummarize_range('sro_brin', 0); -+ brin_desummarize_range -+------------------------ -+ -+(1 row) -+ -+SELECT brin_summarize_range('sro_brin', 0); -+ brin_summarize_range -+---------------------- -+ 1 -+(1 row) -+ -+DROP TABLE sro_tab; -+-- Check with a partitioned table -+CREATE TABLE sro_ptab (a int) PARTITION BY RANGE (a); -+ALTER TABLE sro_ptab OWNER TO regress_sro_user; -+CREATE TABLE sro_part PARTITION OF sro_ptab FOR VALUES FROM (1) TO (10); -+ALTER TABLE sro_part OWNER TO regress_sro_user; -+INSERT INTO sro_ptab VALUES (1), (2), (3); -+CREATE INDEX sro_pidx ON sro_ptab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+REINDEX TABLE sro_ptab; -+REINDEX INDEX CONCURRENTLY sro_pidx; - SET SESSION AUTHORIZATION regress_sro_user; - CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS - 'GRANT regress_priv_group2 TO regress_sro_user'; -@@ -1373,6 +1428,22 @@ CONTEXT: SQL function "unwanted_grant" statement 1 - SQL statement "SELECT unwanted_grant()" - PL/pgSQL function sro_trojan() line 1 at PERFORM - SQL function "mv_action" statement 1 -+-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions() -+SET SESSION AUTHORIZATION regress_sro_user; -+CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int -+ IMMUTABLE LANGUAGE plpgsql AS $$ -+BEGIN -+ PERFORM unwanted_grant(); -+ RAISE WARNING 'owned'; -+ RETURN 1; -+EXCEPTION WHEN OTHERS THEN -+ RETURN 2; -+END$$; -+CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c; -+CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0; -+\c - -+REFRESH MATERIALIZED VIEW CONCURRENTLY sro_index_mv; -+REFRESH MATERIALIZED VIEW sro_index_mv; - DROP OWNED BY regress_sro_user; - DROP ROLE regress_sro_user; - -- Admin options -diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql -index 34fbf0e..c0b88a6 100644 ---- a/src/test/regress/sql/privileges.sql -+++ b/src/test/regress/sql/privileges.sql -@@ -826,6 +826,53 @@ SELECT has_table_privilege('regress_priv_user1', 'atest4', 'SELECT WITH GRANT OP - \c - - CREATE ROLE regress_sro_user; - -+-- Check that index expressions and predicates are run as the table's owner -+ -+-- A dummy index function checking current_user -+CREATE FUNCTION sro_ifun(int) RETURNS int AS $$ -+BEGIN -+ -- Below we set the table's owner to regress_sro_user -+ ASSERT current_user = 'regress_sro_user', -+ format('sro_ifun(%s) called by %s', $1, current_user); -+ RETURN $1; -+END; -+$$ LANGUAGE plpgsql IMMUTABLE; -+-- Create a table owned by regress_sro_user -+CREATE TABLE sro_tab (a int); -+ALTER TABLE sro_tab OWNER TO regress_sro_user; -+INSERT INTO sro_tab VALUES (1), (2), (3); -+-- Create an expression index with a predicate -+CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+DROP INDEX sro_idx; -+-- Do the same concurrently -+CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+-- REINDEX -+REINDEX TABLE sro_tab; -+REINDEX INDEX sro_idx; -+REINDEX TABLE CONCURRENTLY sro_tab; -+DROP INDEX sro_idx; -+-- CLUSTER -+CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))); -+CLUSTER sro_tab USING sro_cluster_idx; -+DROP INDEX sro_cluster_idx; -+-- BRIN index -+CREATE INDEX sro_brin ON sro_tab USING brin ((sro_ifun(a) + sro_ifun(0))); -+SELECT brin_desummarize_range('sro_brin', 0); -+SELECT brin_summarize_range('sro_brin', 0); -+DROP TABLE sro_tab; -+-- Check with a partitioned table -+CREATE TABLE sro_ptab (a int) PARTITION BY RANGE (a); -+ALTER TABLE sro_ptab OWNER TO regress_sro_user; -+CREATE TABLE sro_part PARTITION OF sro_ptab FOR VALUES FROM (1) TO (10); -+ALTER TABLE sro_part OWNER TO regress_sro_user; -+INSERT INTO sro_ptab VALUES (1), (2), (3); -+CREATE INDEX sro_pidx ON sro_ptab ((sro_ifun(a) + sro_ifun(0))) -+ WHERE sro_ifun(a + 10) > sro_ifun(10); -+REINDEX TABLE sro_ptab; -+REINDEX INDEX CONCURRENTLY sro_pidx; -+ - SET SESSION AUTHORIZATION regress_sro_user; - CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS - 'GRANT regress_priv_group2 TO regress_sro_user'; -@@ -852,6 +899,23 @@ REFRESH MATERIALIZED VIEW sro_mv; - REFRESH MATERIALIZED VIEW sro_mv; - BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT; - -+-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions() -+SET SESSION AUTHORIZATION regress_sro_user; -+CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int -+ IMMUTABLE LANGUAGE plpgsql AS $$ -+BEGIN -+ PERFORM unwanted_grant(); -+ RAISE WARNING 'owned'; -+ RETURN 1; -+EXCEPTION WHEN OTHERS THEN -+ RETURN 2; -+END$$; -+CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c; -+CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0; -+\c - -+REFRESH MATERIALIZED VIEW CONCURRENTLY sro_index_mv; -+REFRESH MATERIALIZED VIEW sro_index_mv; -+ - DROP OWNED BY regress_sro_user; - DROP ROLE regress_sro_user; - --- -2.25.1 - diff --git a/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch b/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch deleted file mode 100644 index 6417d8a2b7..0000000000 --- a/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch +++ /dev/null @@ -1,904 +0,0 @@ -From 84375c1db25ef650902cf80712495fc514b0ff63 Mon Sep 17 00:00:00 2001 -From: Hitendra Prajapati <hprajapati@mvista.com> -Date: Thu, 13 Oct 2022 10:35:32 +0530 -Subject: [PATCH] CVE-2022-2625 - -Upstream-Status: Backport [https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5579726bd60a6e7afb04a3548bced348cd5ffd89] -CVE: CVE-2022-2625 -Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> ---- - doc/src/sgml/extend.sgml | 11 -- - src/backend/catalog/pg_collation.c | 49 ++++-- - src/backend/catalog/pg_depend.c | 74 ++++++++- - src/backend/catalog/pg_operator.c | 2 +- - src/backend/catalog/pg_type.c | 7 +- - src/backend/commands/createas.c | 18 ++- - src/backend/commands/foreigncmds.c | 19 ++- - src/backend/commands/schemacmds.c | 25 ++- - src/backend/commands/sequence.c | 8 + - src/backend/commands/statscmds.c | 4 + - src/backend/commands/view.c | 16 +- - src/backend/parser/parse_utilcmd.c | 10 ++ - src/include/catalog/dependency.h | 2 + - src/test/modules/test_extensions/Makefile | 5 +- - .../expected/test_extensions.out | 153 ++++++++++++++++++ - .../test_extensions/sql/test_extensions.sql | 110 +++++++++++++ - .../test_ext_cine--1.0--1.1.sql | 26 +++ - .../test_extensions/test_ext_cine--1.0.sql | 25 +++ - .../test_extensions/test_ext_cine.control | 3 + - .../test_extensions/test_ext_cor--1.0.sql | 20 +++ - .../test_extensions/test_ext_cor.control | 3 + - 21 files changed, 540 insertions(+), 50 deletions(-) - create mode 100644 src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql - create mode 100644 src/test/modules/test_extensions/test_ext_cine--1.0.sql - create mode 100644 src/test/modules/test_extensions/test_ext_cine.control - create mode 100644 src/test/modules/test_extensions/test_ext_cor--1.0.sql - create mode 100644 src/test/modules/test_extensions/test_ext_cor.control - -diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml -index 53f2638..bcc7a80 100644 ---- a/doc/src/sgml/extend.sgml -+++ b/doc/src/sgml/extend.sgml -@@ -1109,17 +1109,6 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</replaceabl - <varname>search_path</varname>. However, no mechanism currently exists - to require that. - </para> -- -- <para> -- Do <emphasis>not</emphasis> use <command>CREATE OR REPLACE -- FUNCTION</command>, except in an update script that must change the -- definition of a function that is known to be an extension member -- already. (Likewise for other <literal>OR REPLACE</literal> options.) -- Using <literal>OR REPLACE</literal> unnecessarily not only has a risk -- of accidentally overwriting someone else's function, but it creates a -- security hazard since the overwritten function would still be owned by -- its original owner, who could modify it. -- </para> - </sect3> - </sect2> - -diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c -index dd99d53..ba4c3ef 100644 ---- a/src/backend/catalog/pg_collation.c -+++ b/src/backend/catalog/pg_collation.c -@@ -78,15 +78,25 @@ CollationCreate(const char *collname, Oid collnamespace, - * friendlier error message. The unique index provides a backstop against - * race conditions. - */ -- if (SearchSysCacheExists3(COLLNAMEENCNSP, -- PointerGetDatum(collname), -- Int32GetDatum(collencoding), -- ObjectIdGetDatum(collnamespace))) -+ oid = GetSysCacheOid3(COLLNAMEENCNSP, -+ Anum_pg_collation_oid, -+ PointerGetDatum(collname), -+ Int32GetDatum(collencoding), -+ ObjectIdGetDatum(collnamespace)); -+ if (OidIsValid(oid)) - { - if (quiet) - return InvalidOid; - else if (if_not_exists) - { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(myself, CollationRelationId, oid); -+ checkMembershipInCurrentExtension(&myself); -+ -+ /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_OBJECT), - collencoding == -1 -@@ -116,16 +126,19 @@ CollationCreate(const char *collname, Oid collnamespace, - * so we take a ShareRowExclusiveLock earlier, to protect against - * concurrent changes fooling this check. - */ -- if ((collencoding == -1 && -- SearchSysCacheExists3(COLLNAMEENCNSP, -- PointerGetDatum(collname), -- Int32GetDatum(GetDatabaseEncoding()), -- ObjectIdGetDatum(collnamespace))) || -- (collencoding != -1 && -- SearchSysCacheExists3(COLLNAMEENCNSP, -- PointerGetDatum(collname), -- Int32GetDatum(-1), -- ObjectIdGetDatum(collnamespace)))) -+ if (collencoding == -1) -+ oid = GetSysCacheOid3(COLLNAMEENCNSP, -+ Anum_pg_collation_oid, -+ PointerGetDatum(collname), -+ Int32GetDatum(GetDatabaseEncoding()), -+ ObjectIdGetDatum(collnamespace)); -+ else -+ oid = GetSysCacheOid3(COLLNAMEENCNSP, -+ Anum_pg_collation_oid, -+ PointerGetDatum(collname), -+ Int32GetDatum(-1), -+ ObjectIdGetDatum(collnamespace)); -+ if (OidIsValid(oid)) - { - if (quiet) - { -@@ -134,6 +147,14 @@ CollationCreate(const char *collname, Oid collnamespace, - } - else if (if_not_exists) - { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(myself, CollationRelationId, oid); -+ checkMembershipInCurrentExtension(&myself); -+ -+ /* OK to skip */ - table_close(rel, NoLock); - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_OBJECT), -diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c -index 9ffadbb..71c7cef 100644 ---- a/src/backend/catalog/pg_depend.c -+++ b/src/backend/catalog/pg_depend.c -@@ -124,15 +124,23 @@ recordMultipleDependencies(const ObjectAddress *depender, - - /* - * If we are executing a CREATE EXTENSION operation, mark the given object -- * as being a member of the extension. Otherwise, do nothing. -+ * as being a member of the extension, or check that it already is one. -+ * Otherwise, do nothing. - * - * This must be called during creation of any user-definable object type - * that could be a member of an extension. - * -- * If isReplace is true, the object already existed (or might have already -- * existed), so we must check for a pre-existing extension membership entry. -- * Passing false is a guarantee that the object is newly created, and so -- * could not already be a member of any extension. -+ * isReplace must be true if the object already existed, and false if it is -+ * newly created. In the former case we insist that it already be a member -+ * of the current extension. In the latter case we can skip checking whether -+ * it is already a member of any extension. -+ * -+ * Note: isReplace = true is typically used when updating a object in -+ * CREATE OR REPLACE and similar commands. We used to allow the target -+ * object to not already be an extension member, instead silently absorbing -+ * it into the current extension. However, this was both error-prone -+ * (extensions might accidentally overwrite free-standing objects) and -+ * a security hazard (since the object would retain its previous ownership). - */ - void - recordDependencyOnCurrentExtension(const ObjectAddress *object, -@@ -150,6 +158,12 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object, - { - Oid oldext; - -+ /* -+ * Side note: these catalog lookups are safe only because the -+ * object is a pre-existing one. In the not-isReplace case, the -+ * caller has most likely not yet done a CommandCounterIncrement -+ * that would make the new object visible. -+ */ - oldext = getExtensionOfObject(object->classId, object->objectId); - if (OidIsValid(oldext)) - { -@@ -163,6 +177,13 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object, - getObjectDescription(object), - get_extension_name(oldext)))); - } -+ /* It's a free-standing object, so reject */ -+ ereport(ERROR, -+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), -+ errmsg("%s is not a member of extension \"%s\"", -+ getObjectDescription(object), -+ get_extension_name(CurrentExtensionObject)), -+ errdetail("An extension is not allowed to replace an object that it does not own."))); - } - - /* OK, record it as a member of CurrentExtensionObject */ -@@ -174,6 +195,49 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object, - } - } - -+/* -+ * If we are executing a CREATE EXTENSION operation, check that the given -+ * object is a member of the extension, and throw an error if it isn't. -+ * Otherwise, do nothing. -+ * -+ * This must be called whenever a CREATE IF NOT EXISTS operation (for an -+ * object type that can be an extension member) has found that an object of -+ * the desired name already exists. It is insecure for an extension to use -+ * IF NOT EXISTS except when the conflicting object is already an extension -+ * member; otherwise a hostile user could substitute an object with arbitrary -+ * properties. -+ */ -+void -+checkMembershipInCurrentExtension(const ObjectAddress *object) -+{ -+ /* -+ * This is actually the same condition tested in -+ * recordDependencyOnCurrentExtension; but we want to issue a -+ * differently-worded error, and anyway it would be pretty confusing to -+ * call recordDependencyOnCurrentExtension in these circumstances. -+ */ -+ -+ /* Only whole objects can be extension members */ -+ Assert(object->objectSubId == 0); -+ -+ if (creating_extension) -+ { -+ Oid oldext; -+ -+ oldext = getExtensionOfObject(object->classId, object->objectId); -+ /* If already a member of this extension, OK */ -+ if (oldext == CurrentExtensionObject) -+ return; -+ /* Else complain */ -+ ereport(ERROR, -+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), -+ errmsg("%s is not a member of extension \"%s\"", -+ getObjectDescription(object), -+ get_extension_name(CurrentExtensionObject)), -+ errdetail("An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns."))); -+ } -+} -+ - /* - * deleteDependencyRecordsFor -- delete all records with given depender - * classId/objectId. Returns the number of records deleted. -diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c -index bcaa26c..84784e6 100644 ---- a/src/backend/catalog/pg_operator.c -+++ b/src/backend/catalog/pg_operator.c -@@ -867,7 +867,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) - oper->oprowner); - - /* Dependency on extension */ -- recordDependencyOnCurrentExtension(&myself, true); -+ recordDependencyOnCurrentExtension(&myself, isUpdate); - - return myself; - } -diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c -index 2a51501..3ff017f 100644 ---- a/src/backend/catalog/pg_type.c -+++ b/src/backend/catalog/pg_type.c -@@ -528,10 +528,9 @@ TypeCreate(Oid newTypeOid, - * If rebuild is true, we remove existing dependencies and rebuild them - * from scratch. This is needed for ALTER TYPE, and also when replacing - * a shell type. We don't remove an existing extension dependency, though. -- * (That means an extension can't absorb a shell type created in another -- * extension, nor ALTER a type created by another extension. Also, if it -- * replaces a free-standing shell type or ALTERs a free-standing type, -- * that type will become a member of the extension.) -+ * That means an extension can't absorb a shell type that is free-standing -+ * or belongs to another extension, nor ALTER a type that is free-standing or -+ * belongs to another extension. - */ - void - GenerateTypeDependencies(Oid typeObjectId, -diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c -index 4c1d909..a68d945 100644 ---- a/src/backend/commands/createas.c -+++ b/src/backend/commands/createas.c -@@ -243,15 +243,27 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, - if (stmt->if_not_exists) - { - Oid nspid; -+ Oid oldrelid; - -- nspid = RangeVarGetCreationNamespace(stmt->into->rel); -+ nspid = RangeVarGetCreationNamespace(into->rel); - -- if (get_relname_relid(stmt->into->rel->relname, nspid)) -+ oldrelid = get_relname_relid(into->rel->relname, nspid); -+ if (OidIsValid(oldrelid)) - { -+ /* -+ * The relation exists and IF NOT EXISTS has been specified. -+ * -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(address, RelationRelationId, oldrelid); -+ checkMembershipInCurrentExtension(&address); -+ -+ /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists, skipping", -- stmt->into->rel->relname))); -+ into->rel->relname))); - return InvalidObjectAddress; - } - } -diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c -index d7bc6e3..bc583c6 100644 ---- a/src/backend/commands/foreigncmds.c -+++ b/src/backend/commands/foreigncmds.c -@@ -887,13 +887,22 @@ CreateForeignServer(CreateForeignServerStmt *stmt) - ownerId = GetUserId(); - - /* -- * Check that there is no other foreign server by this name. Do nothing if -- * IF NOT EXISTS was enforced. -+ * Check that there is no other foreign server by this name. If there is -+ * one, do nothing if IF NOT EXISTS was specified. - */ -- if (GetForeignServerByName(stmt->servername, true) != NULL) -+ srvId = get_foreign_server_oid(stmt->servername, true); -+ if (OidIsValid(srvId)) - { - if (stmt->if_not_exists) - { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(myself, ForeignServerRelationId, srvId); -+ checkMembershipInCurrentExtension(&myself); -+ -+ /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("server \"%s\" already exists, skipping", -@@ -1182,6 +1191,10 @@ CreateUserMapping(CreateUserMappingStmt *stmt) - { - if (stmt->if_not_exists) - { -+ /* -+ * Since user mappings aren't members of extensions (see comments -+ * below), no need for checkMembershipInCurrentExtension here. -+ */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user mapping for \"%s\" already exists for server \"%s\", skipping", -diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c -index 6cf94a3..6bc4edc 100644 ---- a/src/backend/commands/schemacmds.c -+++ b/src/backend/commands/schemacmds.c -@@ -113,14 +113,25 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString, - * the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its - * creation-permission check first, we do likewise. - */ -- if (stmt->if_not_exists && -- SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(schemaName))) -+ if (stmt->if_not_exists) - { -- ereport(NOTICE, -- (errcode(ERRCODE_DUPLICATE_SCHEMA), -- errmsg("schema \"%s\" already exists, skipping", -- schemaName))); -- return InvalidOid; -+ namespaceId = get_namespace_oid(schemaName, true); -+ if (OidIsValid(namespaceId)) -+ { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(address, NamespaceRelationId, namespaceId); -+ checkMembershipInCurrentExtension(&address); -+ -+ /* OK to skip */ -+ ereport(NOTICE, -+ (errcode(ERRCODE_DUPLICATE_SCHEMA), -+ errmsg("schema \"%s\" already exists, skipping", -+ schemaName))); -+ return InvalidOid; -+ } - } - - /* -diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c -index 0960b33..0577184 100644 ---- a/src/backend/commands/sequence.c -+++ b/src/backend/commands/sequence.c -@@ -149,6 +149,14 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) - RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid); - if (OidIsValid(seqoid)) - { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddressSet(address, RelationRelationId, seqoid); -+ checkMembershipInCurrentExtension(&address); -+ -+ /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists, skipping", -diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c -index 5678d31..409cf28 100644 ---- a/src/backend/commands/statscmds.c -+++ b/src/backend/commands/statscmds.c -@@ -173,6 +173,10 @@ CreateStatistics(CreateStatsStmt *stmt) - { - if (stmt->if_not_exists) - { -+ /* -+ * Since stats objects aren't members of extensions (see comments -+ * below), no need for checkMembershipInCurrentExtension here. -+ */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("statistics object \"%s\" already exists, skipping", -diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c -index 87ed453..dd7cc97 100644 ---- a/src/backend/commands/view.c -+++ b/src/backend/commands/view.c -@@ -205,7 +205,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, - CommandCounterIncrement(); - - /* -- * Finally update the view options. -+ * Update the view's options. - * - * The new options list replaces the existing options list, even if - * it's empty. -@@ -218,8 +218,22 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, - /* EventTriggerAlterTableStart called by ProcessUtilitySlow */ - AlterTableInternal(viewOid, atcmds, true); - -+ /* -+ * There is very little to do here to update the view's dependencies. -+ * Most view-level dependency relationships, such as those on the -+ * owner, schema, and associated composite type, aren't changing. -+ * Because we don't allow changing type or collation of an existing -+ * view column, those dependencies of the existing columns don't -+ * change either, while the AT_AddColumnToView machinery took care of -+ * adding such dependencies for new view columns. The dependencies of -+ * the view's query could have changed arbitrarily, but that was dealt -+ * with inside StoreViewQuery. What remains is only to check that -+ * view replacement is allowed when we're creating an extension. -+ */ - ObjectAddressSet(address, RelationRelationId, viewOid); - -+ recordDependencyOnCurrentExtension(&address, true); -+ - /* - * Seems okay, so return the OID of the pre-existing view. - */ -diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c -index 44aa38a..8f4d940 100644 ---- a/src/backend/parser/parse_utilcmd.c -+++ b/src/backend/parser/parse_utilcmd.c -@@ -206,6 +206,16 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) - */ - if (stmt->if_not_exists && OidIsValid(existing_relid)) - { -+ /* -+ * If we are in an extension script, insist that the pre-existing -+ * object be a member of the extension, to avoid security risks. -+ */ -+ ObjectAddress address; -+ -+ ObjectAddressSet(address, RelationRelationId, existing_relid); -+ checkMembershipInCurrentExtension(&address); -+ -+ /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists, skipping", -diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h -index 8b1e3aa..27c7509 100644 ---- a/src/include/catalog/dependency.h -+++ b/src/include/catalog/dependency.h -@@ -201,6 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender, - extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, - bool isReplace); - -+extern void checkMembershipInCurrentExtension(const ObjectAddress *object); -+ - extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, - bool skipExtensionDeps); - -diff --git a/src/test/modules/test_extensions/Makefile b/src/test/modules/test_extensions/Makefile -index d18108e..7428f15 100644 ---- a/src/test/modules/test_extensions/Makefile -+++ b/src/test/modules/test_extensions/Makefile -@@ -4,10 +4,13 @@ MODULE = test_extensions - PGFILEDESC = "test_extensions - regression testing for EXTENSION support" - - EXTENSION = test_ext1 test_ext2 test_ext3 test_ext4 test_ext5 test_ext6 \ -- test_ext7 test_ext8 test_ext_cyclic1 test_ext_cyclic2 -+ test_ext7 test_ext8 test_ext_cine test_ext_cor \ -+ test_ext_cyclic1 test_ext_cyclic2 - DATA = test_ext1--1.0.sql test_ext2--1.0.sql test_ext3--1.0.sql \ - test_ext4--1.0.sql test_ext5--1.0.sql test_ext6--1.0.sql \ - test_ext7--1.0.sql test_ext7--1.0--2.0.sql test_ext8--1.0.sql \ -+ test_ext_cine--1.0.sql test_ext_cine--1.0--1.1.sql \ -+ test_ext_cor--1.0.sql \ - test_ext_cyclic1--1.0.sql test_ext_cyclic2--1.0.sql - - REGRESS = test_extensions test_extdepend -diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out -index b5cbdfc..1e91640 100644 ---- a/src/test/modules/test_extensions/expected/test_extensions.out -+++ b/src/test/modules/test_extensions/expected/test_extensions.out -@@ -154,3 +154,156 @@ DROP TABLE test_ext4_tab; - DROP FUNCTION create_extension_with_temp_schema(); - RESET client_min_messages; - \unset SHOW_CONTEXT -+-- It's generally bad style to use CREATE OR REPLACE unnecessarily. -+-- Test what happens if an extension does it anyway. -+-- Replacing a shell type or operator is sort of like CREATE OR REPLACE; -+-- check that too. -+CREATE FUNCTION ext_cor_func() RETURNS text -+ AS $$ SELECT 'ext_cor_func: original'::text $$ LANGUAGE sql; -+CREATE EXTENSION test_ext_cor; -- fail -+ERROR: function ext_cor_func() is not a member of extension "test_ext_cor" -+DETAIL: An extension is not allowed to replace an object that it does not own. -+SELECT ext_cor_func(); -+ ext_cor_func -+------------------------ -+ ext_cor_func: original -+(1 row) -+ -+DROP FUNCTION ext_cor_func(); -+CREATE VIEW ext_cor_view AS -+ SELECT 'ext_cor_view: original'::text AS col; -+CREATE EXTENSION test_ext_cor; -- fail -+ERROR: view ext_cor_view is not a member of extension "test_ext_cor" -+DETAIL: An extension is not allowed to replace an object that it does not own. -+SELECT ext_cor_func(); -+ERROR: function ext_cor_func() does not exist -+LINE 1: SELECT ext_cor_func(); -+ ^ -+HINT: No function matches the given name and argument types. You might need to add explicit type casts. -+SELECT * FROM ext_cor_view; -+ col -+------------------------ -+ ext_cor_view: original -+(1 row) -+ -+DROP VIEW ext_cor_view; -+CREATE TYPE test_ext_type; -+CREATE EXTENSION test_ext_cor; -- fail -+ERROR: type test_ext_type is not a member of extension "test_ext_cor" -+DETAIL: An extension is not allowed to replace an object that it does not own. -+DROP TYPE test_ext_type; -+-- this makes a shell "point <<@@ polygon" operator too -+CREATE OPERATOR @@>> ( PROCEDURE = poly_contain_pt, -+ LEFTARG = polygon, RIGHTARG = point, -+ COMMUTATOR = <<@@ ); -+CREATE EXTENSION test_ext_cor; -- fail -+ERROR: operator <<@@(point,polygon) is not a member of extension "test_ext_cor" -+DETAIL: An extension is not allowed to replace an object that it does not own. -+DROP OPERATOR <<@@ (point, polygon); -+CREATE EXTENSION test_ext_cor; -- now it should work -+SELECT ext_cor_func(); -+ ext_cor_func -+------------------------------ -+ ext_cor_func: from extension -+(1 row) -+ -+SELECT * FROM ext_cor_view; -+ col -+------------------------------ -+ ext_cor_view: from extension -+(1 row) -+ -+SELECT 'x'::test_ext_type; -+ test_ext_type -+--------------- -+ x -+(1 row) -+ -+SELECT point(0,0) <<@@ polygon(circle(point(0,0),1)); -+ ?column? -+---------- -+ t -+(1 row) -+ -+\dx+ test_ext_cor -+Objects in extension "test_ext_cor" -+ Object description -+------------------------------ -+ function ext_cor_func() -+ operator <<@@(point,polygon) -+ type test_ext_type -+ view ext_cor_view -+(4 rows) -+ -+-- -+-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension -+-- to be doing, but let's at least plug the major security hole in it. -+-- -+CREATE COLLATION ext_cine_coll -+ ( LC_COLLATE = "C", LC_CTYPE = "C" ); -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: collation ext_cine_coll is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP COLLATION ext_cine_coll; -+CREATE MATERIALIZED VIEW ext_cine_mv AS SELECT 11 AS f1; -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: materialized view ext_cine_mv is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP MATERIALIZED VIEW ext_cine_mv; -+CREATE FOREIGN DATA WRAPPER dummy; -+CREATE SERVER ext_cine_srv FOREIGN DATA WRAPPER dummy; -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: server ext_cine_srv is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP SERVER ext_cine_srv; -+CREATE SCHEMA ext_cine_schema; -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: schema ext_cine_schema is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP SCHEMA ext_cine_schema; -+CREATE SEQUENCE ext_cine_seq; -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: sequence ext_cine_seq is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP SEQUENCE ext_cine_seq; -+CREATE TABLE ext_cine_tab1 (x int); -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: table ext_cine_tab1 is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP TABLE ext_cine_tab1; -+CREATE TABLE ext_cine_tab2 AS SELECT 42 AS y; -+CREATE EXTENSION test_ext_cine; -- fail -+ERROR: table ext_cine_tab2 is not a member of extension "test_ext_cine" -+DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns. -+DROP TABLE ext_cine_tab2; -+CREATE EXTENSION test_ext_cine; -+\dx+ test_ext_cine -+Objects in extension "test_ext_cine" -+ Object description -+----------------------------------- -+ collation ext_cine_coll -+ foreign-data wrapper ext_cine_fdw -+ materialized view ext_cine_mv -+ schema ext_cine_schema -+ sequence ext_cine_seq -+ server ext_cine_srv -+ table ext_cine_tab1 -+ table ext_cine_tab2 -+(8 rows) -+ -+ALTER EXTENSION test_ext_cine UPDATE TO '1.1'; -+\dx+ test_ext_cine -+Objects in extension "test_ext_cine" -+ Object description -+----------------------------------- -+ collation ext_cine_coll -+ foreign-data wrapper ext_cine_fdw -+ materialized view ext_cine_mv -+ schema ext_cine_schema -+ sequence ext_cine_seq -+ server ext_cine_srv -+ table ext_cine_tab1 -+ table ext_cine_tab2 -+ table ext_cine_tab3 -+(9 rows) -+ -diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql b/src/test/modules/test_extensions/sql/test_extensions.sql -index f505466..b3d4579 100644 ---- a/src/test/modules/test_extensions/sql/test_extensions.sql -+++ b/src/test/modules/test_extensions/sql/test_extensions.sql -@@ -93,3 +93,113 @@ DROP TABLE test_ext4_tab; - DROP FUNCTION create_extension_with_temp_schema(); - RESET client_min_messages; - \unset SHOW_CONTEXT -+ -+-- It's generally bad style to use CREATE OR REPLACE unnecessarily. -+-- Test what happens if an extension does it anyway. -+-- Replacing a shell type or operator is sort of like CREATE OR REPLACE; -+-- check that too. -+ -+CREATE FUNCTION ext_cor_func() RETURNS text -+ AS $$ SELECT 'ext_cor_func: original'::text $$ LANGUAGE sql; -+ -+CREATE EXTENSION test_ext_cor; -- fail -+ -+SELECT ext_cor_func(); -+ -+DROP FUNCTION ext_cor_func(); -+ -+CREATE VIEW ext_cor_view AS -+ SELECT 'ext_cor_view: original'::text AS col; -+ -+CREATE EXTENSION test_ext_cor; -- fail -+ -+SELECT ext_cor_func(); -+ -+SELECT * FROM ext_cor_view; -+ -+DROP VIEW ext_cor_view; -+ -+CREATE TYPE test_ext_type; -+ -+CREATE EXTENSION test_ext_cor; -- fail -+ -+DROP TYPE test_ext_type; -+ -+-- this makes a shell "point <<@@ polygon" operator too -+CREATE OPERATOR @@>> ( PROCEDURE = poly_contain_pt, -+ LEFTARG = polygon, RIGHTARG = point, -+ COMMUTATOR = <<@@ ); -+ -+CREATE EXTENSION test_ext_cor; -- fail -+ -+DROP OPERATOR <<@@ (point, polygon); -+ -+CREATE EXTENSION test_ext_cor; -- now it should work -+ -+SELECT ext_cor_func(); -+ -+SELECT * FROM ext_cor_view; -+ -+SELECT 'x'::test_ext_type; -+ -+SELECT point(0,0) <<@@ polygon(circle(point(0,0),1)); -+ -+\dx+ test_ext_cor -+ -+-- -+-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension -+-- to be doing, but let's at least plug the major security hole in it. -+-- -+ -+CREATE COLLATION ext_cine_coll -+ ( LC_COLLATE = "C", LC_CTYPE = "C" ); -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP COLLATION ext_cine_coll; -+ -+CREATE MATERIALIZED VIEW ext_cine_mv AS SELECT 11 AS f1; -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP MATERIALIZED VIEW ext_cine_mv; -+ -+CREATE FOREIGN DATA WRAPPER dummy; -+ -+CREATE SERVER ext_cine_srv FOREIGN DATA WRAPPER dummy; -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP SERVER ext_cine_srv; -+ -+CREATE SCHEMA ext_cine_schema; -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP SCHEMA ext_cine_schema; -+ -+CREATE SEQUENCE ext_cine_seq; -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP SEQUENCE ext_cine_seq; -+ -+CREATE TABLE ext_cine_tab1 (x int); -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP TABLE ext_cine_tab1; -+ -+CREATE TABLE ext_cine_tab2 AS SELECT 42 AS y; -+ -+CREATE EXTENSION test_ext_cine; -- fail -+ -+DROP TABLE ext_cine_tab2; -+ -+CREATE EXTENSION test_ext_cine; -+ -+\dx+ test_ext_cine -+ -+ALTER EXTENSION test_ext_cine UPDATE TO '1.1'; -+ -+\dx+ test_ext_cine -diff --git a/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql b/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql -new file mode 100644 -index 0000000..6dadfd2 ---- /dev/null -+++ b/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql -@@ -0,0 +1,26 @@ -+/* src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql */ -+-- complain if script is sourced in psql, rather than via ALTER EXTENSION -+\echo Use "ALTER EXTENSION test_ext_cine UPDATE TO '1.1'" to load this file. \quit -+ -+-- -+-- These are the same commands as in the 1.0 script; we expect them -+-- to do nothing. -+-- -+ -+CREATE COLLATION IF NOT EXISTS ext_cine_coll -+ ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ); -+ -+CREATE MATERIALIZED VIEW IF NOT EXISTS ext_cine_mv AS SELECT 42 AS f1; -+ -+CREATE SERVER IF NOT EXISTS ext_cine_srv FOREIGN DATA WRAPPER ext_cine_fdw; -+ -+CREATE SCHEMA IF NOT EXISTS ext_cine_schema; -+ -+CREATE SEQUENCE IF NOT EXISTS ext_cine_seq; -+ -+CREATE TABLE IF NOT EXISTS ext_cine_tab1 (x int); -+ -+CREATE TABLE IF NOT EXISTS ext_cine_tab2 AS SELECT 42 AS y; -+ -+-- just to verify the script ran -+CREATE TABLE ext_cine_tab3 (z int); -diff --git a/src/test/modules/test_extensions/test_ext_cine--1.0.sql b/src/test/modules/test_extensions/test_ext_cine--1.0.sql -new file mode 100644 -index 0000000..01408ff ---- /dev/null -+++ b/src/test/modules/test_extensions/test_ext_cine--1.0.sql -@@ -0,0 +1,25 @@ -+/* src/test/modules/test_extensions/test_ext_cine--1.0.sql */ -+-- complain if script is sourced in psql, rather than via CREATE EXTENSION -+\echo Use "CREATE EXTENSION test_ext_cine" to load this file. \quit -+ -+-- -+-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension -+-- to be doing, but let's at least plug the major security hole in it. -+-- -+ -+CREATE COLLATION IF NOT EXISTS ext_cine_coll -+ ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ); -+ -+CREATE MATERIALIZED VIEW IF NOT EXISTS ext_cine_mv AS SELECT 42 AS f1; -+ -+CREATE FOREIGN DATA WRAPPER ext_cine_fdw; -+ -+CREATE SERVER IF NOT EXISTS ext_cine_srv FOREIGN DATA WRAPPER ext_cine_fdw; -+ -+CREATE SCHEMA IF NOT EXISTS ext_cine_schema; -+ -+CREATE SEQUENCE IF NOT EXISTS ext_cine_seq; -+ -+CREATE TABLE IF NOT EXISTS ext_cine_tab1 (x int); -+ -+CREATE TABLE IF NOT EXISTS ext_cine_tab2 AS SELECT 42 AS y; -diff --git a/src/test/modules/test_extensions/test_ext_cine.control b/src/test/modules/test_extensions/test_ext_cine.control -new file mode 100644 -index 0000000..ced713b ---- /dev/null -+++ b/src/test/modules/test_extensions/test_ext_cine.control -@@ -0,0 +1,3 @@ -+comment = 'Test extension using CREATE IF NOT EXISTS' -+default_version = '1.0' -+relocatable = true -diff --git a/src/test/modules/test_extensions/test_ext_cor--1.0.sql b/src/test/modules/test_extensions/test_ext_cor--1.0.sql -new file mode 100644 -index 0000000..2e8d89c ---- /dev/null -+++ b/src/test/modules/test_extensions/test_ext_cor--1.0.sql -@@ -0,0 +1,20 @@ -+/* src/test/modules/test_extensions/test_ext_cor--1.0.sql */ -+-- complain if script is sourced in psql, rather than via CREATE EXTENSION -+\echo Use "CREATE EXTENSION test_ext_cor" to load this file. \quit -+ -+-- It's generally bad style to use CREATE OR REPLACE unnecessarily. -+-- Test what happens if an extension does it anyway. -+ -+CREATE OR REPLACE FUNCTION ext_cor_func() RETURNS text -+ AS $$ SELECT 'ext_cor_func: from extension'::text $$ LANGUAGE sql; -+ -+CREATE OR REPLACE VIEW ext_cor_view AS -+ SELECT 'ext_cor_view: from extension'::text AS col; -+ -+-- These are for testing replacement of a shell type/operator, which works -+-- enough like an implicit OR REPLACE to be important to check. -+ -+CREATE TYPE test_ext_type AS ENUM('x', 'y'); -+ -+CREATE OPERATOR <<@@ ( PROCEDURE = pt_contained_poly, -+ LEFTARG = point, RIGHTARG = polygon ); -diff --git a/src/test/modules/test_extensions/test_ext_cor.control b/src/test/modules/test_extensions/test_ext_cor.control -new file mode 100644 -index 0000000..0e972e5 ---- /dev/null -+++ b/src/test/modules/test_extensions/test_ext_cor.control -@@ -0,0 +1,3 @@ -+comment = 'Test extension using CREATE OR REPLACE' -+default_version = '1.0' -+relocatable = true --- -2.25.1 - diff --git a/meta-oe/recipes-dbs/postgresql/files/not-check-libperl.patch b/meta-oe/recipes-dbs/postgresql/files/not-check-libperl.patch index 22b62d9ded..eb6226b179 100644 --- a/meta-oe/recipes-dbs/postgresql/files/not-check-libperl.patch +++ b/meta-oe/recipes-dbs/postgresql/files/not-check-libperl.patch @@ -19,11 +19,11 @@ Signed-off-by: Changqing Li <changqing.li@windriver.com> configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/configure.in b/configure.in -index b98b9bb..8584677 100644 ---- a/configure.in -+++ b/configure.in -@@ -2211,7 +2211,7 @@ Use --without-tcl to disable building PL/Tcl.]) +Index: postgresql-12.16/configure.in +=================================================================== +--- postgresql-12.16.orig/configure.in ++++ postgresql-12.16/configure.in +@@ -2357,7 +2357,7 @@ Use --without-tcl to disable building PL fi # check for <perl.h> @@ -32,6 +32,3 @@ index b98b9bb..8584677 100644 ac_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $perl_includespec" AC_CHECK_HEADER(perl.h, [], [AC_MSG_ERROR([header file <perl.h> is required for Perl])], --- -2.7.4 - diff --git a/meta-oe/recipes-dbs/postgresql/files/remove_duplicate.patch b/meta-oe/recipes-dbs/postgresql/files/remove_duplicate.patch deleted file mode 100644 index 92a3dcc710..0000000000 --- a/meta-oe/recipes-dbs/postgresql/files/remove_duplicate.patch +++ /dev/null @@ -1,38 +0,0 @@ -Remove duplicate code for riscv - -Upstream-Status: Pending -Signed-off-by: Khem Raj <raj.khem@gmail.com> - ---- a/src/include/storage/s_lock.h -+++ b/src/include/storage/s_lock.h -@@ -341,30 +341,6 @@ tas(volatile slock_t *lock) - #endif /* HAVE_GCC__SYNC_INT32_TAS */ - #endif /* __arm__ || __arm || __aarch64__ || __aarch64 || __riscv */ - -- --/* -- * RISC-V likewise uses __sync_lock_test_and_set(int *, int) if available. -- */ --#if defined(__riscv) --#ifdef HAVE_GCC__SYNC_INT32_TAS --#define HAS_TEST_AND_SET -- --#define TAS(lock) tas(lock) -- --typedef int slock_t; -- --static __inline__ int --tas(volatile slock_t *lock) --{ -- return __sync_lock_test_and_set(lock, 1); --} -- --#define S_UNLOCK(lock) __sync_lock_release(lock) -- --#endif /* HAVE_GCC__SYNC_INT32_TAS */ --#endif /* __riscv */ -- -- - /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ - #if defined(__s390__) || defined(__s390x__) - #define HAS_TEST_AND_SET diff --git a/meta-oe/recipes-dbs/postgresql/postgresql_12.18.bb b/meta-oe/recipes-dbs/postgresql/postgresql_12.18.bb new file mode 100644 index 0000000000..44074a233c --- /dev/null +++ b/meta-oe/recipes-dbs/postgresql/postgresql_12.18.bb @@ -0,0 +1,11 @@ +require postgresql.inc + +LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=89afbb2d7716371015101c2b2cb4297a" + +SRC_URI += "\ + file://not-check-libperl.patch \ + file://0001-Add-support-for-RISC-V.patch \ + file://0001-Improve-reproducibility.patch \ +" + +SRC_URI[sha256sum] = "4f9919725d941ce9868e07fe1ed1d3a86748599b483386547583928b74c3918a" diff --git a/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb b/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb deleted file mode 100644 index 860e821b20..0000000000 --- a/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb +++ /dev/null @@ -1,14 +0,0 @@ -require postgresql.inc - -LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=255f15687738db8068fbe9b938c90217" - -SRC_URI += "\ - file://not-check-libperl.patch \ - file://0001-Add-support-for-RISC-V.patch \ - file://0001-Improve-reproducibility.patch \ - file://remove_duplicate.patch \ - file://CVE-2022-1552.patch \ - file://CVE-2022-2625.patch \ -" - -SRC_URI[sha256sum] = "89fda2de33ed04a98548e43f3ee5f15b882be17505d631fe0dd1a540a2b56dce" |