diff options
| author | Ashish Sharma <asharma@mvista.com> | 2024-09-09 20:31:27 +0530 |
|---|---|---|
| committer | Armin Kuster <akuster808@gmail.com> | 2024-09-09 15:33:19 -0400 |
| commit | a89f9b2db0744bdda6e1e3d4482891860e6d7893 (patch) | |
| tree | 2e5ba1ed2fbabda85371768458e74346443a606a | |
| parent | 4f0f1bd855ff14c2434c25d72a79f99173bef487 (diff) | |
| download | meta-openembedded-a89f9b2db0744bdda6e1e3d4482891860e6d7893.tar.gz | |
postgresql: Backport fix for CVE-2024-7348
Upstream-Status: Backport []https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=79c7a7e29695a32fef2e65682be224b8d61ec972
Signed-off-by: Ashish Sharma <asharma@mvista.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
| -rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/CVE-2024-7348.patch | 583 | ||||
| -rw-r--r-- | meta-oe/recipes-dbs/postgresql/postgresql_16.3.bb | 1 |
2 files changed, 584 insertions, 0 deletions
diff --git a/meta-oe/recipes-dbs/postgresql/files/CVE-2024-7348.patch b/meta-oe/recipes-dbs/postgresql/files/CVE-2024-7348.patch new file mode 100644 index 0000000000..10c2fa3efe --- /dev/null +++ b/meta-oe/recipes-dbs/postgresql/files/CVE-2024-7348.patch | |||
| @@ -0,0 +1,583 @@ | |||
| 1 | From 6aba85a4b0a0e60126cc7c598b3e010e272516ec Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Masahiko Sawada <msawada@postgresql.org> | ||
| 3 | Date: Mon, 5 Aug 2024 06:05:28 -0700 | ||
| 4 | Subject: [PATCH] Restrict accesses to non-system views and foreign tables | ||
| 5 | during pg_dump. | ||
| 6 | |||
| 7 | When pg_dump retrieves the list of database objects and performs the | ||
| 8 | data dump, there was possibility that objects are replaced with others | ||
| 9 | of the same name, such as views, and access them. This vulnerability | ||
| 10 | could result in code execution with superuser privileges during the | ||
| 11 | pg_dump process. | ||
| 12 | |||
| 13 | This issue can arise when dumping data of sequences, foreign | ||
| 14 | tables (only 13 or later), or tables registered with a WHERE clause in | ||
| 15 | the extension configuration table. | ||
| 16 | |||
| 17 | To address this, pg_dump now utilizes the newly introduced | ||
| 18 | restrict_nonsystem_relation_kind GUC parameter to restrict the | ||
| 19 | accesses to non-system views and foreign tables during the dump | ||
| 20 | process. This new GUC parameter is added to back branches too, but | ||
| 21 | these changes do not require cluster recreation. | ||
| 22 | |||
| 23 | Back-patch to all supported branches. | ||
| 24 | |||
| 25 | Reviewed-by: Noah Misch | ||
| 26 | Security: CVE-2024-7348 | ||
| 27 | Backpatch-through: 12 | ||
| 28 | |||
| 29 | Upstream-Status: Backport from [https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=79c7a7e29695a32fef2e65682be224b8d61ec972] | ||
| 30 | CVE: CVE-2024-7348 | ||
| 31 | Signed-off-by: Ashish Sharma <asharma@mvista.com> | ||
| 32 | |||
| 33 | .../postgres_fdw/expected/postgres_fdw.out | 11 ++++ | ||
| 34 | contrib/postgres_fdw/sql/postgres_fdw.sql | 8 +++ | ||
| 35 | doc/src/sgml/config.sgml | 17 +++++ | ||
| 36 | doc/src/sgml/ref/pg_dump.sgml | 8 +++ | ||
| 37 | src/backend/foreign/foreign.c | 10 +++ | ||
| 38 | src/backend/optimizer/plan/createplan.c | 13 ++++ | ||
| 39 | src/backend/optimizer/util/plancat.c | 12 ++++ | ||
| 40 | src/backend/rewrite/rewriteHandler.c | 17 +++++ | ||
| 41 | src/backend/tcop/postgres.c | 64 +++++++++++++++++++ | ||
| 42 | src/backend/utils/misc/guc_tables.c | 12 ++++ | ||
| 43 | src/bin/pg_dump/pg_dump.c | 47 ++++++++++++++ | ||
| 44 | src/include/tcop/tcopprot.h | 6 ++ | ||
| 45 | src/include/utils/guc_hooks.h | 3 + | ||
| 46 | src/test/regress/expected/create_view.out | 19 +++++- | ||
| 47 | src/test/regress/sql/create_view.sql | 9 +++ | ||
| 48 | 15 files changed, 255 insertions(+), 1 deletion(-) | ||
| 49 | |||
| 50 | diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out | ||
| 51 | index a6fd3f6ff0..9b7a7eed05 100644 | ||
| 52 | --- a/contrib/postgres_fdw/expected/postgres_fdw.out | ||
| 53 | +++ b/contrib/postgres_fdw/expected/postgres_fdw.out | ||
| 54 | @@ -637,6 +637,17 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; | ||
| 55 | Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST | ||
| 56 | (3 rows) | ||
| 57 | |||
| 58 | +-- test restriction on non-system foreign tables. | ||
| 59 | +SET restrict_nonsystem_relation_kind TO 'foreign-table'; | ||
| 60 | +SELECT * from ft1 where c1 < 1; -- ERROR | ||
| 61 | +ERROR: access to non-system foreign table is restricted | ||
| 62 | +INSERT INTO ft1 (c1) VALUES (1); -- ERROR | ||
| 63 | +ERROR: access to non-system foreign table is restricted | ||
| 64 | +DELETE FROM ft1 WHERE c1 = 1; -- ERROR | ||
| 65 | +ERROR: access to non-system foreign table is restricted | ||
| 66 | +TRUNCATE ft1; -- ERROR | ||
| 67 | +ERROR: access to non-system foreign table is restricted | ||
| 68 | +RESET restrict_nonsystem_relation_kind; | ||
| 69 | -- =================================================================== | ||
| 70 | -- WHERE with remotely-executable conditions | ||
| 71 | -- =================================================================== | ||
| 72 | diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql | ||
| 73 | index 1c1dedd991..80cc3f9d8e 100644 | ||
| 74 | --- a/contrib/postgres_fdw/sql/postgres_fdw.sql | ||
| 75 | +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql | ||
| 76 | @@ -327,6 +327,14 @@ DELETE FROM loct_empty; | ||
| 77 | ANALYZE ft_empty; | ||
| 78 | EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; | ||
| 79 | |||
| 80 | +-- test restriction on non-system foreign tables. | ||
| 81 | +SET restrict_nonsystem_relation_kind TO 'foreign-table'; | ||
| 82 | +SELECT * from ft1 where c1 < 1; -- ERROR | ||
| 83 | +INSERT INTO ft1 (c1) VALUES (1); -- ERROR | ||
| 84 | +DELETE FROM ft1 WHERE c1 = 1; -- ERROR | ||
| 85 | +TRUNCATE ft1; -- ERROR | ||
| 86 | +RESET restrict_nonsystem_relation_kind; | ||
| 87 | + | ||
| 88 | -- =================================================================== | ||
| 89 | -- WHERE with remotely-executable conditions | ||
| 90 | -- =================================================================== | ||
| 91 | diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml | ||
| 92 | index e8c5d2a3b7..69c4bc614f 100644 | ||
| 93 | --- a/doc/src/sgml/config.sgml | ||
| 94 | +++ b/doc/src/sgml/config.sgml | ||
| 95 | @@ -9564,6 +9564,23 @@ SET XML OPTION { DOCUMENT | CONTENT }; | ||
| 96 | </listitem> | ||
| 97 | </varlistentry> | ||
| 98 | |||
| 99 | + <varlistentry id="guc-restrict-nonsystem-relation-kind" xreflabel="restrict_nonsystem_relation_kind"> | ||
| 100 | + <term><varname>restrict_nonsystem_relation_kind</varname> (<type>string</type>) | ||
| 101 | + <indexterm> | ||
| 102 | + <primary><varname>restrict_nonsystem_relation_kind</varname></primary> | ||
| 103 | + <secondary>configuration parameter</secondary> | ||
| 104 | + </indexterm> | ||
| 105 | + </term> | ||
| 106 | + <listitem> | ||
| 107 | + <para> | ||
| 108 | + This variable specifies relation kind to which access is restricted. | ||
| 109 | + It contains a comma-separated list of relation kind. Currently, the | ||
| 110 | + supported relation kinds are <literal>view</literal> and | ||
| 111 | + <literal>foreign-table</literal>. | ||
| 112 | + </para> | ||
| 113 | + </listitem> | ||
| 114 | + </varlistentry> | ||
| 115 | + | ||
| 116 | </variablelist> | ||
| 117 | </sect2> | ||
| 118 | <sect2 id="runtime-config-client-format"> | ||
| 119 | diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml | ||
| 120 | index 7ff5d04c73..b879c30c18 100644 | ||
| 121 | --- a/doc/src/sgml/ref/pg_dump.sgml | ||
| 122 | +++ b/doc/src/sgml/ref/pg_dump.sgml | ||
| 123 | @@ -868,6 +868,14 @@ PostgreSQL documentation | ||
| 124 | The only exception is that an empty pattern is disallowed. | ||
| 125 | </para> | ||
| 126 | |||
| 127 | + <note> | ||
| 128 | + <para> | ||
| 129 | + Using wildcards in <option>--include-foreign-data</option> may result | ||
| 130 | + in access to unexpected foreign servers. Also, to use this option securely, | ||
| 131 | + make sure that the named server must have a trusted owner. | ||
| 132 | + </para> | ||
| 133 | + </note> | ||
| 134 | + | ||
| 135 | <note> | ||
| 136 | <para> | ||
| 137 | When <option>--include-foreign-data</option> is specified, | ||
| 138 | diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c | ||
| 139 | index ca3ad55b62..7335838af3 100644 | ||
| 140 | --- a/src/backend/foreign/foreign.c | ||
| 141 | +++ b/src/backend/foreign/foreign.c | ||
| 142 | @@ -23,6 +23,7 @@ | ||
| 143 | #include "funcapi.h" | ||
| 144 | #include "lib/stringinfo.h" | ||
| 145 | #include "miscadmin.h" | ||
| 146 | +#include "tcop/tcopprot.h" | ||
| 147 | #include "utils/builtins.h" | ||
| 148 | #include "utils/memutils.h" | ||
| 149 | #include "utils/rel.h" | ||
| 150 | @@ -323,6 +324,15 @@ GetFdwRoutine(Oid fdwhandler) | ||
| 151 | Datum datum; | ||
| 152 | FdwRoutine *routine; | ||
| 153 | |||
| 154 | + /* Check if the access to foreign tables is restricted */ | ||
| 155 | + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0)) | ||
| 156 | + { | ||
| 157 | + /* there must not be built-in FDW handler */ | ||
| 158 | + ereport(ERROR, | ||
| 159 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||
| 160 | + errmsg("access to non-system foreign table is restricted"))); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | datum = OidFunctionCall0(fdwhandler); | ||
| 164 | routine = (FdwRoutine *) DatumGetPointer(datum); | ||
| 165 | |||
| 166 | diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c | ||
| 167 | index 4bb38160b3..974c50b29f 100644 | ||
| 168 | --- a/src/backend/optimizer/plan/createplan.c | ||
| 169 | +++ b/src/backend/optimizer/plan/createplan.c | ||
| 170 | @@ -40,6 +40,7 @@ | ||
| 171 | #include "parser/parse_clause.h" | ||
| 172 | #include "parser/parsetree.h" | ||
| 173 | #include "partitioning/partprune.h" | ||
| 174 | +#include "tcop/tcopprot.h" | ||
| 175 | #include "utils/lsyscache.h" | ||
| 176 | |||
| 177 | |||
| 178 | @@ -7090,7 +7091,19 @@ make_modifytable(PlannerInfo *root, Plan *subplan, | ||
| 179 | |||
| 180 | if (rte->rtekind == RTE_RELATION && | ||
| 181 | rte->relkind == RELKIND_FOREIGN_TABLE) | ||
| 182 | + { | ||
| 183 | + /* Check if the access to foreign tables is restricted */ | ||
| 184 | + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0)) | ||
| 185 | + { | ||
| 186 | + /* there must not be built-in foreign tables */ | ||
| 187 | + Assert(rte->relid >= FirstNormalObjectId); | ||
| 188 | + ereport(ERROR, | ||
| 189 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||
| 190 | + errmsg("access to non-system foreign table is restricted"))); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | fdwroutine = GetFdwRoutineByRelId(rte->relid); | ||
| 194 | + } | ||
| 195 | else | ||
| 196 | fdwroutine = NULL; | ||
| 197 | } | ||
| 198 | diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c | ||
| 199 | index 07c4ba384a..1a3045479f 100644 | ||
| 200 | --- a/src/backend/optimizer/util/plancat.c | ||
| 201 | +++ b/src/backend/optimizer/util/plancat.c | ||
| 202 | @@ -47,6 +47,7 @@ | ||
| 203 | #include "rewrite/rewriteManip.h" | ||
| 204 | #include "statistics/statistics.h" | ||
| 205 | #include "storage/bufmgr.h" | ||
| 206 | +#include "tcop/tcopprot.h" | ||
| 207 | #include "utils/builtins.h" | ||
| 208 | #include "utils/lsyscache.h" | ||
| 209 | #include "utils/partcache.h" | ||
| 210 | @@ -500,6 +501,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, | ||
| 211 | /* Grab foreign-table info using the relcache, while we have it */ | ||
| 212 | if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) | ||
| 213 | { | ||
| 214 | + /* Check if the access to foreign tables is restricted */ | ||
| 215 | + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0)) | ||
| 216 | + { | ||
| 217 | + /* there must not be built-in foreign tables */ | ||
| 218 | + Assert(RelationGetRelid(relation) >= FirstNormalObjectId); | ||
| 219 | + | ||
| 220 | + ereport(ERROR, | ||
| 221 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||
| 222 | + errmsg("access to non-system foreign table is restricted"))); | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation)); | ||
| 226 | rel->fdwroutine = GetFdwRoutineForRelation(relation, true); | ||
| 227 | } | ||
| 228 | diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c | ||
| 229 | index 6cef936f82..9cd96fd17e 100644 | ||
| 230 | --- a/src/backend/rewrite/rewriteHandler.c | ||
| 231 | +++ b/src/backend/rewrite/rewriteHandler.c | ||
| 232 | @@ -41,6 +41,7 @@ | ||
| 233 | #include "rewrite/rewriteManip.h" | ||
| 234 | #include "rewrite/rewriteSearchCycle.h" | ||
| 235 | #include "rewrite/rowsecurity.h" | ||
| 236 | +#include "tcop/tcopprot.h" | ||
| 237 | #include "utils/builtins.h" | ||
| 238 | #include "utils/lsyscache.h" | ||
| 239 | #include "utils/rel.h" | ||
| 240 | @@ -1740,6 +1741,14 @@ ApplyRetrieveRule(Query *parsetree, | ||
| 241 | if (rule->qual != NULL) | ||
| 242 | elog(ERROR, "cannot handle qualified ON SELECT rule"); | ||
| 243 | |||
| 244 | + /* Check if the expansion of non-system views are restricted */ | ||
| 245 | + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 && | ||
| 246 | + RelationGetRelid(relation) >= FirstNormalObjectId)) | ||
| 247 | + ereport(ERROR, | ||
| 248 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||
| 249 | + errmsg("access to non-system view \"%s\" is restricted", | ||
| 250 | + RelationGetRelationName(relation)))); | ||
| 251 | + | ||
| 252 | if (rt_index == parsetree->resultRelation) | ||
| 253 | { | ||
| 254 | /* | ||
| 255 | @@ -3104,6 +3113,14 @@ | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | + /* Check if the expansion of non-system views are restricted */ | ||
| 260 | + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 && | ||
| 261 | + RelationGetRelid(view) >= FirstNormalObjectId)) | ||
| 262 | + ereport(ERROR, | ||
| 263 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||
| 264 | + errmsg("access to non-system view \"%s\" is restricted", | ||
| 265 | + RelationGetRelationName(view)))); | ||
| 266 | + | ||
| 267 | /* | ||
| 268 | * For INSERT/UPDATE the modified columns must all be updatable. Note that | ||
| 269 | * we get the modified columns from the query's targetlist, not from the | ||
| 270 | diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c | ||
| 271 | index 36cc99ec9c..e7d486ca2f 100644 | ||
| 272 | --- a/src/backend/tcop/postgres.c | ||
| 273 | +++ b/src/backend/tcop/postgres.c | ||
| 274 | @@ -77,6 +77,7 @@ | ||
| 275 | #include "utils/snapmgr.h" | ||
| 276 | #include "utils/timeout.h" | ||
| 277 | #include "utils/timestamp.h" | ||
| 278 | +#include "utils/varlena.h" | ||
| 279 | |||
| 280 | /* ---------------- | ||
| 281 | * global variables | ||
| 282 | @@ -101,6 +102,9 @@ int PostAuthDelay = 0; | ||
| 283 | /* Time between checks that the client is still connected. */ | ||
| 284 | int client_connection_check_interval = 0; | ||
| 285 | |||
| 286 | +/* flags for non-system relation kinds to restrict use */ | ||
| 287 | +int restrict_nonsystem_relation_kind; | ||
| 288 | + | ||
| 289 | /* ---------------- | ||
| 290 | * private typedefs etc | ||
| 291 | * ---------------- | ||
| 292 | @@ -3628,6 +3632,66 @@ check_log_stats(bool *newval, void **extra, GucSource source) | ||
| 293 | return true; | ||
| 294 | } | ||
| 295 | |||
| 296 | +/* | ||
| 297 | + * GUC check_hook for restrict_nonsystem_relation_kind | ||
| 298 | + */ | ||
| 299 | +bool | ||
| 300 | +check_restrict_nonsystem_relation_kind(char **newval, void **extra, GucSource source) | ||
| 301 | +{ | ||
| 302 | + char *rawstring; | ||
| 303 | + List *elemlist; | ||
| 304 | + ListCell *l; | ||
| 305 | + int flags = 0; | ||
| 306 | + | ||
| 307 | + /* Need a modifiable copy of string */ | ||
| 308 | + rawstring = pstrdup(*newval); | ||
| 309 | + | ||
| 310 | + if (!SplitIdentifierString(rawstring, ',', &elemlist)) | ||
| 311 | + { | ||
| 312 | + /* syntax error in list */ | ||
| 313 | + GUC_check_errdetail("List syntax is invalid."); | ||
| 314 | + pfree(rawstring); | ||
| 315 | + list_free(elemlist); | ||
| 316 | + return false; | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + foreach(l, elemlist) | ||
| 320 | + { | ||
| 321 | + char *tok = (char *) lfirst(l); | ||
| 322 | + | ||
| 323 | + if (pg_strcasecmp(tok, "view") == 0) | ||
| 324 | + flags |= RESTRICT_RELKIND_VIEW; | ||
| 325 | + else if (pg_strcasecmp(tok, "foreign-table") == 0) | ||
| 326 | + flags |= RESTRICT_RELKIND_FOREIGN_TABLE; | ||
| 327 | + else | ||
| 328 | + { | ||
| 329 | + GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); | ||
| 330 | + pfree(rawstring); | ||
| 331 | + list_free(elemlist); | ||
| 332 | + return false; | ||
| 333 | + } | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + pfree(rawstring); | ||
| 337 | + list_free(elemlist); | ||
| 338 | + | ||
| 339 | + /* Save the flags in *extra, for use by the assign function */ | ||
| 340 | + *extra = guc_malloc(ERROR, sizeof(int)); | ||
| 341 | + *((int *) *extra) = flags; | ||
| 342 | + | ||
| 343 | + return true; | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +/* | ||
| 347 | + * GUC assign_hook for restrict_nonsystem_relation_kind | ||
| 348 | + */ | ||
| 349 | +void | ||
| 350 | +assign_restrict_nonsystem_relation_kind(const char *newval, void *extra) | ||
| 351 | +{ | ||
| 352 | + int *flags = (int *) extra; | ||
| 353 | + | ||
| 354 | + restrict_nonsystem_relation_kind = *flags; | ||
| 355 | +} | ||
| 356 | |||
| 357 | /* | ||
| 358 | * set_debug_options --- apply "-d N" command line option | ||
| 359 | diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c | ||
| 360 | index b078b934a7..a515ecde97 100644 | ||
| 361 | --- a/src/backend/utils/misc/guc_tables.c | ||
| 362 | +++ b/src/backend/utils/misc/guc_tables.c | ||
| 363 | @@ -564,6 +564,7 @@ static char *server_encoding_string; | ||
| 364 | static char *server_version_string; | ||
| 365 | static int server_version_num; | ||
| 366 | static char *debug_io_direct_string; | ||
| 367 | +static char *restrict_nonsystem_relation_kind_string; | ||
| 368 | |||
| 369 | #ifdef HAVE_SYSLOG | ||
| 370 | #define DEFAULT_SYSLOG_FACILITY LOG_LOCAL0 | ||
| 371 | @@ -4549,6 +4550,17 @@ struct config_string ConfigureNamesString[] = | ||
| 372 | check_debug_io_direct, assign_debug_io_direct, NULL | ||
| 373 | }, | ||
| 374 | |||
| 375 | + { | ||
| 376 | + {"restrict_nonsystem_relation_kind", PGC_USERSET, CLIENT_CONN_STATEMENT, | ||
| 377 | + gettext_noop("Sets relation kinds of non-system relation to restrict use"), | ||
| 378 | + NULL, | ||
| 379 | + GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE | ||
| 380 | + }, | ||
| 381 | + &restrict_nonsystem_relation_kind_string, | ||
| 382 | + "", | ||
| 383 | + check_restrict_nonsystem_relation_kind, assign_restrict_nonsystem_relation_kind, NULL | ||
| 384 | + }, | ||
| 385 | + | ||
| 386 | /* End-of-list marker */ | ||
| 387 | { | ||
| 388 | {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL | ||
| 389 | diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c | ||
| 390 | index 300fe071fc..1694ff55f8 100644 | ||
| 391 | --- a/src/bin/pg_dump/pg_dump.c | ||
| 392 | +++ b/src/bin/pg_dump/pg_dump.c | ||
| 393 | @@ -324,6 +324,7 @@ static bool nonemptyReloptions(const char *reloptions); | ||
| 394 | static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, | ||
| 395 | const char *prefix, Archive *fout); | ||
| 396 | static char *get_synchronized_snapshot(Archive *fout); | ||
| 397 | +static void set_restrict_relation_kind(Archive *AH, const char *value); | ||
| 398 | static void setupDumpWorker(Archive *AH); | ||
| 399 | static TableInfo *getRootTableInfo(const TableInfo *tbinfo); | ||
| 400 | static bool forcePartitionRootLoad(const TableInfo *tbinfo); | ||
| 401 | @@ -1252,6 +1253,13 @@ setup_connection(Archive *AH, const char *dumpencoding, | ||
| 402 | ExecuteSqlStatement(AH, "SET row_security = off"); | ||
| 403 | } | ||
| 404 | |||
| 405 | + /* | ||
| 406 | + * For security reasons, we restrict the expansion of non-system views and | ||
| 407 | + * access to foreign tables during the pg_dump process. This restriction | ||
| 408 | + * is adjusted when dumping foreign table data. | ||
| 409 | + */ | ||
| 410 | + set_restrict_relation_kind(AH, "view, foreign-table"); | ||
| 411 | + | ||
| 412 | /* | ||
| 413 | * Initialize prepared-query state to "nothing prepared". We do this here | ||
| 414 | * so that a parallel dump worker will have its own state. | ||
| 415 | @@ -2114,6 +2122,10 @@ dumpTableData_copy(Archive *fout, const void *dcontext) | ||
| 416 | */ | ||
| 417 | if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE) | ||
| 418 | { | ||
| 419 | + /* Temporary allows to access to foreign tables to dump data */ | ||
| 420 | + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) | ||
| 421 | + set_restrict_relation_kind(fout, "view"); | ||
| 422 | + | ||
| 423 | appendPQExpBufferStr(q, "COPY (SELECT "); | ||
| 424 | /* klugery to get rid of parens in column list */ | ||
| 425 | if (strlen(column_list) > 2) | ||
| 426 | @@ -2225,6 +2237,11 @@ dumpTableData_copy(Archive *fout, const void *dcontext) | ||
| 427 | classname); | ||
| 428 | |||
| 429 | destroyPQExpBuffer(q); | ||
| 430 | + | ||
| 431 | + /* Revert back the setting */ | ||
| 432 | + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) | ||
| 433 | + set_restrict_relation_kind(fout, "view, foreign-table"); | ||
| 434 | + | ||
| 435 | return 1; | ||
| 436 | } | ||
| 437 | |||
| 438 | @@ -2251,6 +2268,10 @@ dumpTableData_insert(Archive *fout, const void *dcontext) | ||
| 439 | int rows_per_statement = dopt->dump_inserts; | ||
| 440 | int rows_this_statement = 0; | ||
| 441 | |||
| 442 | + /* Temporary allows to access to foreign tables to dump data */ | ||
| 443 | + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) | ||
| 444 | + set_restrict_relation_kind(fout, "view"); | ||
| 445 | + | ||
| 446 | /* | ||
| 447 | * If we're going to emit INSERTs with column names, the most efficient | ||
| 448 | * way to deal with generated columns is to exclude them entirely. For | ||
| 449 | @@ -2490,6 +2511,10 @@ dumpTableData_insert(Archive *fout, const void *dcontext) | ||
| 450 | destroyPQExpBuffer(insertStmt); | ||
| 451 | free(attgenerated); | ||
| 452 | |||
| 453 | + /* Revert back the setting */ | ||
| 454 | + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) | ||
| 455 | + set_restrict_relation_kind(fout, "view, foreign-table"); | ||
| 456 | + | ||
| 457 | return 1; | ||
| 458 | } | ||
| 459 | |||
| 460 | @@ -4590,6 +4615,28 @@ is_superuser(Archive *fout) | ||
| 461 | return false; | ||
| 462 | } | ||
| 463 | |||
| 464 | +/* | ||
| 465 | + * Set the given value to restrict_nonsystem_relation_kind value. Since | ||
| 466 | + * restrict_nonsystem_relation_kind is introduced in minor version releases, | ||
| 467 | + * the setting query is effective only where available. | ||
| 468 | + */ | ||
| 469 | +static void | ||
| 470 | +set_restrict_relation_kind(Archive *AH, const char *value) | ||
| 471 | +{ | ||
| 472 | + PQExpBuffer query = createPQExpBuffer(); | ||
| 473 | + PGresult *res; | ||
| 474 | + | ||
| 475 | + appendPQExpBuffer(query, | ||
| 476 | + "SELECT set_config(name, '%s', false) " | ||
| 477 | + "FROM pg_settings " | ||
| 478 | + "WHERE name = 'restrict_nonsystem_relation_kind'", | ||
| 479 | + value); | ||
| 480 | + res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK); | ||
| 481 | + | ||
| 482 | + PQclear(res); | ||
| 483 | + destroyPQExpBuffer(query); | ||
| 484 | +} | ||
| 485 | + | ||
| 486 | /* | ||
| 487 | * getSubscriptions | ||
| 488 | * get information about subscriptions | ||
| 489 | diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h | ||
| 490 | index abd7b4fff3..e529e9f06c 100644 | ||
| 491 | --- a/src/include/tcop/tcopprot.h | ||
| 492 | +++ b/src/include/tcop/tcopprot.h | ||
| 493 | @@ -43,6 +43,12 @@ typedef enum | ||
| 494 | |||
| 495 | extern PGDLLIMPORT int log_statement; | ||
| 496 | |||
| 497 | +/* Flags for restrict_nonsystem_relation_kind value */ | ||
| 498 | +#define RESTRICT_RELKIND_VIEW 0x01 | ||
| 499 | +#define RESTRICT_RELKIND_FOREIGN_TABLE 0x02 | ||
| 500 | + | ||
| 501 | +extern PGDLLIMPORT int restrict_nonsystem_relation_kind; | ||
| 502 | + | ||
| 503 | extern List *pg_parse_query(const char *query_string); | ||
| 504 | extern List *pg_rewrite_query(Query *query); | ||
| 505 | extern List *pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, | ||
| 506 | diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h | ||
| 507 | index 952293a1c3..0ea33fede9 100644 | ||
| 508 | --- a/src/include/utils/guc_hooks.h | ||
| 509 | +++ b/src/include/utils/guc_hooks.h | ||
| 510 | @@ -118,6 +118,9 @@ extern void assign_recovery_target_xid(const char *newval, void *extra); | ||
| 511 | extern bool check_role(char **newval, void **extra, GucSource source); | ||
| 512 | extern void assign_role(const char *newval, void *extra); | ||
| 513 | extern const char *show_role(void); | ||
| 514 | +extern bool check_restrict_nonsystem_relation_kind(char **newval, void **extra, | ||
| 515 | + GucSource source); | ||
| 516 | +extern void assign_restrict_nonsystem_relation_kind(const char *newval, void *extra); | ||
| 517 | extern bool check_search_path(char **newval, void **extra, GucSource source); | ||
| 518 | extern void assign_search_path(const char *newval, void *extra); | ||
| 519 | extern bool check_session_authorization(char **newval, void **extra, GucSource source); | ||
| 520 | diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out | ||
| 521 | index 61825ef7d4..f3f8c7b5a2 100644 | ||
| 522 | --- a/src/test/regress/expected/create_view.out | ||
| 523 | +++ b/src/test/regress/expected/create_view.out | ||
| 524 | @@ -2202,6 +2202,21 @@ select pg_get_viewdef('tt26v', true); | ||
| 525 | FROM ( VALUES (1,2,3)) v(x, y, z); | ||
| 526 | (1 row) | ||
| 527 | |||
| 528 | +-- test restriction on non-system view expansion. | ||
| 529 | +create table tt27v_tbl (a int); | ||
| 530 | +create view tt27v as select a from tt27v_tbl; | ||
| 531 | +set restrict_nonsystem_relation_kind to 'view'; | ||
| 532 | +select a from tt27v where a > 0; -- Error | ||
| 533 | +ERROR: access to non-system view "tt27v" is restricted | ||
| 534 | +insert into tt27v values (1); -- Error | ||
| 535 | +ERROR: access to non-system view "tt27v" is restricted | ||
| 536 | +select viewname from pg_views where viewname = 'tt27v'; -- Ok to access a system view. | ||
| 537 | + viewname | ||
| 538 | +---------- | ||
| 539 | + tt27v | ||
| 540 | +(1 row) | ||
| 541 | + | ||
| 542 | +reset restrict_nonsystem_relation_kind; | ||
| 543 | -- clean up all the random objects we made above | ||
| 544 | DROP SCHEMA temp_view_test CASCADE; | ||
| 545 | NOTICE: drop cascades to 27 other objects | ||
| 546 | @@ -2233,7 +2248,7 @@ drop cascades to view aliased_view_2 | ||
| 547 | drop cascades to view aliased_view_3 | ||
| 548 | drop cascades to view aliased_view_4 | ||
| 549 | DROP SCHEMA testviewschm2 CASCADE; | ||
| 550 | -NOTICE: drop cascades to 77 other objects | ||
| 551 | +NOTICE: drop cascades to 79 other objects | ||
| 552 | DETAIL: drop cascades to table t1 | ||
| 553 | drop cascades to view temporal1 | ||
| 554 | drop cascades to view temporal2 | ||
| 555 | @@ -2311,3 +2326,5 @@ drop cascades to view tt23v | ||
| 556 | drop cascades to view tt24v | ||
| 557 | drop cascades to view tt25v | ||
| 558 | drop cascades to view tt26v | ||
| 559 | +drop cascades to table tt27v_tbl | ||
| 560 | +drop cascades to view tt27v | ||
| 561 | diff --git a/src/test/regress/sql/create_view.sql b/src/test/regress/sql/create_view.sql | ||
| 562 | index 8838a40f7a..3a78be1b0c 100644 | ||
| 563 | --- a/src/test/regress/sql/create_view.sql | ||
| 564 | +++ b/src/test/regress/sql/create_view.sql | ||
| 565 | @@ -813,6 +813,15 @@ select x + y + z as c1, | ||
| 566 | from (values(1,2,3)) v(x,y,z); | ||
| 567 | select pg_get_viewdef('tt26v', true); | ||
| 568 | |||
| 569 | +-- test restriction on non-system view expansion. | ||
| 570 | +create table tt27v_tbl (a int); | ||
| 571 | +create view tt27v as select a from tt27v_tbl; | ||
| 572 | +set restrict_nonsystem_relation_kind to 'view'; | ||
| 573 | +select a from tt27v where a > 0; -- Error | ||
| 574 | +insert into tt27v values (1); -- Error | ||
| 575 | +select viewname from pg_views where viewname = 'tt27v'; -- Ok to access a system view. | ||
| 576 | +reset restrict_nonsystem_relation_kind; | ||
| 577 | + | ||
| 578 | -- clean up all the random objects we made above | ||
| 579 | DROP SCHEMA temp_view_test CASCADE; | ||
| 580 | DROP SCHEMA testviewschm2 CASCADE; | ||
| 581 | -- | ||
| 582 | 2.30.2 | ||
| 583 | |||
diff --git a/meta-oe/recipes-dbs/postgresql/postgresql_16.3.bb b/meta-oe/recipes-dbs/postgresql/postgresql_16.3.bb index 6df719cd98..31f427503b 100644 --- a/meta-oe/recipes-dbs/postgresql/postgresql_16.3.bb +++ b/meta-oe/recipes-dbs/postgresql/postgresql_16.3.bb | |||
| @@ -9,6 +9,7 @@ SRC_URI += "\ | |||
| 9 | file://0003-configure.ac-bypass-autoconf-2.69-version-check.patch \ | 9 | file://0003-configure.ac-bypass-autoconf-2.69-version-check.patch \ |
| 10 | file://0004-config_info.c-not-expose-build-info.patch \ | 10 | file://0004-config_info.c-not-expose-build-info.patch \ |
| 11 | file://0005-postgresql-fix-ptest-failure-of-sysviews.patch \ | 11 | file://0005-postgresql-fix-ptest-failure-of-sysviews.patch \ |
| 12 | file://CVE-2024-7348.patch \ | ||
| 12 | " | 13 | " |
| 13 | 14 | ||
| 14 | SRC_URI[sha256sum] = "331963d5d3dc4caf4216a049fa40b66d6bcb8c730615859411b9518764e60585" | 15 | SRC_URI[sha256sum] = "331963d5d3dc4caf4216a049fa40b66d6bcb8c730615859411b9518764e60585" |
