Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbbc94ab

Browse files
Restrict accesses to non-system views and foreign tables during pg_dump.
When pg_dump retrieves the list of database objects and performs thedata dump, there was possibility that objects are replaced with othersof the same name, such as views, and access them. This vulnerabilitycould result in code execution with superuser privileges during thepg_dump process.This issue can arise when dumping data of sequences, foreigntables (only 13 or later), or tables registered with a WHERE clause inthe extension configuration table.To address this, pg_dump now utilizes the newly introducedrestrict_nonsystem_relation_kind GUC parameter to restrict theaccesses to non-system views and foreign tables during the dumpprocess. This new GUC parameter is added to back branches too, butthese changes do not require cluster recreation.Back-patch to all supported branches.Reviewed-by: Noah MischSecurity:CVE-2024-7348Backpatch-through: 12
1 parent1d454d4 commitbbc94ab

File tree

14 files changed

+250
-1
lines changed

14 files changed

+250
-1
lines changed

‎contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,15 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1;
620620
Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST
621621
(3 rows)
622622

623+
-- test restriction on non-system foreign tables.
624+
SET restrict_nonsystem_relation_kind TO 'foreign-table';
625+
SELECT * from ft1 where c1 < 1; -- ERROR
626+
ERROR: access to non-system foreign table is restricted
627+
INSERT INTO ft1 (c1) VALUES (1); -- ERROR
628+
ERROR: access to non-system foreign table is restricted
629+
DELETE FROM ft1 WHERE c1 = 1; -- ERROR
630+
ERROR: access to non-system foreign table is restricted
631+
RESET restrict_nonsystem_relation_kind;
623632
-- ===================================================================
624633
-- WHERE with remotely-executable conditions
625634
-- ===================================================================

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ DELETE FROM loct_empty;
310310
ANALYZE ft_empty;
311311
EXPLAIN (VERBOSE, COSTS OFF)SELECT*FROM ft_emptyORDER BY c1;
312312

313+
-- test restriction on non-system foreign tables.
314+
SET restrict_nonsystem_relation_kind TO'foreign-table';
315+
SELECT*from ft1where c1<1;-- ERROR
316+
INSERT INTO ft1 (c1)VALUES (1);-- ERROR
317+
DELETEFROM ft1WHERE c1=1;-- ERROR
318+
RESET restrict_nonsystem_relation_kind;
319+
313320
-- ===================================================================
314321
-- WHERE with remotely-executable conditions
315322
-- ===================================================================

‎doc/src/sgml/config.sgml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8581,6 +8581,23 @@ SET XML OPTION { DOCUMENT | CONTENT };
85818581
</listitem>
85828582
</varlistentry>
85838583

8584+
<varlistentry id="guc-restrict-nonsystem-relation-kind" xreflabel="restrict_nonsystem_relation_kind">
8585+
<term><varname>restrict_nonsystem_relation_kind</varname> (<type>string</type>)
8586+
<indexterm>
8587+
<primary><varname>restrict_nonsystem_relation_kind</varname></primary>
8588+
<secondary>configuration parameter</secondary>
8589+
</indexterm>
8590+
</term>
8591+
<listitem>
8592+
<para>
8593+
This variable specifies relation kind to which access is restricted.
8594+
It contains a comma-separated list of relation kind. Currently, the
8595+
supported relation kinds are <literal>view</literal> and
8596+
<literal>foreign-table</literal>.
8597+
</para>
8598+
</listitem>
8599+
</varlistentry>
8600+
85848601
</variablelist>
85858602
</sect2>
85868603
<sect2 id="runtime-config-client-format">

‎doc/src/sgml/ref/pg_dump.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,14 @@ PostgreSQL documentation
793793
The only exception is that an empty pattern is disallowed.
794794
</para>
795795

796+
<note>
797+
<para>
798+
Using wildcards in <option>--include-foreign-data</option> may result
799+
in access to unexpected foreign servers. Also, to use this option securely,
800+
make sure that the named server must have a trusted owner.
801+
</para>
802+
</note>
803+
796804
<note>
797805
<para>
798806
When <option>--include-foreign-data</option> is specified,

‎src/backend/foreign/foreign.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include"foreign/foreign.h"
2323
#include"lib/stringinfo.h"
2424
#include"miscadmin.h"
25+
#include"tcop/tcopprot.h"
2526
#include"utils/builtins.h"
2627
#include"utils/memutils.h"
2728
#include"utils/rel.h"
@@ -321,6 +322,15 @@ GetFdwRoutine(Oid fdwhandler)
321322
Datumdatum;
322323
FdwRoutine*routine;
323324

325+
/* Check if the access to foreign tables is restricted */
326+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_FOREIGN_TABLE)!=0))
327+
{
328+
/* there must not be built-in FDW handler */
329+
ereport(ERROR,
330+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
331+
errmsg("access to non-system foreign table is restricted")));
332+
}
333+
324334
datum=OidFunctionCall0(fdwhandler);
325335
routine= (FdwRoutine*)DatumGetPointer(datum);
326336

‎src/backend/optimizer/plan/createplan.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include"parser/parse_clause.h"
4141
#include"parser/parsetree.h"
4242
#include"partitioning/partprune.h"
43+
#include"tcop/tcopprot.h"
4344
#include"utils/lsyscache.h"
4445

4546

@@ -6819,7 +6820,19 @@ make_modifytable(PlannerInfo *root,
68196820

68206821
Assert(rte->rtekind==RTE_RELATION);
68216822
if (rte->relkind==RELKIND_FOREIGN_TABLE)
6823+
{
6824+
/* Check if the access to foreign tables is restricted */
6825+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_FOREIGN_TABLE)!=0))
6826+
{
6827+
/* there must not be built-in foreign tables */
6828+
Assert(rte->relid >=FirstNormalObjectId);
6829+
ereport(ERROR,
6830+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6831+
errmsg("access to non-system foreign table is restricted")));
6832+
}
6833+
68226834
fdwroutine=GetFdwRoutineByRelId(rte->relid);
6835+
}
68236836
else
68246837
fdwroutine=NULL;
68256838
}

‎src/backend/optimizer/util/plancat.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include"rewrite/rewriteManip.h"
4747
#include"statistics/statistics.h"
4848
#include"storage/bufmgr.h"
49+
#include"tcop/tcopprot.h"
4950
#include"utils/builtins.h"
5051
#include"utils/lsyscache.h"
5152
#include"utils/partcache.h"
@@ -463,6 +464,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
463464
/* Grab foreign-table info using the relcache, while we have it */
464465
if (relation->rd_rel->relkind==RELKIND_FOREIGN_TABLE)
465466
{
467+
/* Check if the access to foreign tables is restricted */
468+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_FOREIGN_TABLE)!=0))
469+
{
470+
/* there must not be built-in foreign tables */
471+
Assert(RelationGetRelid(relation) >=FirstNormalObjectId);
472+
473+
ereport(ERROR,
474+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
475+
errmsg("access to non-system foreign table is restricted")));
476+
}
477+
466478
rel->serverid=GetForeignServerIdByRelId(RelationGetRelid(relation));
467479
rel->fdwroutine=GetFdwRoutineForRelation(relation, true);
468480
}

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include"rewrite/rewriteHandler.h"
4141
#include"rewrite/rewriteManip.h"
4242
#include"rewrite/rowsecurity.h"
43+
#include"tcop/tcopprot.h"
4344
#include"utils/builtins.h"
4445
#include"utils/lsyscache.h"
4546
#include"utils/rel.h"
@@ -1678,6 +1679,14 @@ ApplyRetrieveRule(Query *parsetree,
16781679
if (rule->qual!=NULL)
16791680
elog(ERROR,"cannot handle qualified ON SELECT rule");
16801681

1682+
/* Check if the expansion of non-system views are restricted */
1683+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_VIEW)!=0&&
1684+
RelationGetRelid(relation) >=FirstNormalObjectId))
1685+
ereport(ERROR,
1686+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1687+
errmsg("access to non-system view \"%s\" is restricted",
1688+
RelationGetRelationName(relation))));
1689+
16811690
if (rt_index==parsetree->resultRelation)
16821691
{
16831692
/*
@@ -3055,6 +3064,14 @@ rewriteTargetView(Query *parsetree, Relation view)
30553064
}
30563065
}
30573066

3067+
/* Check if the expansion of non-system views are restricted */
3068+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_VIEW)!=0&&
3069+
RelationGetRelid(view) >=FirstNormalObjectId))
3070+
ereport(ERROR,
3071+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3072+
errmsg("access to non-system view \"%s\" is restricted",
3073+
RelationGetRelationName(view))));
3074+
30583075
/*
30593076
* For INSERT/UPDATE the modified columns must all be updatable.
30603077
*/

‎src/backend/tcop/postgres.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include"utils/snapmgr.h"
8080
#include"utils/timeout.h"
8181
#include"utils/timestamp.h"
82+
#include"utils/varlena.h"
8283

8384
/* ----------------
8485
*global variables
@@ -101,6 +102,8 @@ intmax_stack_depth = 100;
101102
intPostAuthDelay=0;
102103

103104

105+
/* flags for non-system relation kinds to restrict use */
106+
intrestrict_nonsystem_relation_kind;
104107

105108
/* ----------------
106109
*private variables
@@ -3441,6 +3444,66 @@ assign_max_stack_depth(int newval, void *extra)
34413444
max_stack_depth_bytes=newval_bytes;
34423445
}
34433446

3447+
/*
3448+
* GUC check_hook for restrict_nonsystem_relation_kind
3449+
*/
3450+
bool
3451+
check_restrict_nonsystem_relation_kind(char**newval,void**extra,GucSourcesource)
3452+
{
3453+
char*rawstring;
3454+
List*elemlist;
3455+
ListCell*l;
3456+
intflags=0;
3457+
3458+
/* Need a modifiable copy of string */
3459+
rawstring=pstrdup(*newval);
3460+
3461+
if (!SplitIdentifierString(rawstring,',',&elemlist))
3462+
{
3463+
/* syntax error in list */
3464+
GUC_check_errdetail("List syntax is invalid.");
3465+
pfree(rawstring);
3466+
list_free(elemlist);
3467+
return false;
3468+
}
3469+
3470+
foreach(l,elemlist)
3471+
{
3472+
char*tok= (char*)lfirst(l);
3473+
3474+
if (pg_strcasecmp(tok,"view")==0)
3475+
flags |=RESTRICT_RELKIND_VIEW;
3476+
elseif (pg_strcasecmp(tok,"foreign-table")==0)
3477+
flags |=RESTRICT_RELKIND_FOREIGN_TABLE;
3478+
else
3479+
{
3480+
GUC_check_errdetail("Unrecognized key word: \"%s\".",tok);
3481+
pfree(rawstring);
3482+
list_free(elemlist);
3483+
return false;
3484+
}
3485+
}
3486+
3487+
pfree(rawstring);
3488+
list_free(elemlist);
3489+
3490+
/* Save the flags in *extra, for use by the assign function */
3491+
*extra=malloc(sizeof(int));
3492+
*((int*)*extra)=flags;
3493+
3494+
return true;
3495+
}
3496+
3497+
/*
3498+
* GUC assign_hook for restrict_nonsystem_relation_kind
3499+
*/
3500+
void
3501+
assign_restrict_nonsystem_relation_kind(constchar*newval,void*extra)
3502+
{
3503+
int*flags= (int*)extra;
3504+
3505+
restrict_nonsystem_relation_kind=*flags;
3506+
}
34443507

34453508
/*
34463509
* set_debug_options --- apply "-d N" command line option

‎src/backend/utils/misc/guc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ static char *recovery_target_string;
620620
staticchar*recovery_target_xid_string;
621621
staticchar*recovery_target_name_string;
622622
staticchar*recovery_target_lsn_string;
623+
staticchar*restrict_nonsystem_relation_kind_string;
623624

624625

625626
/* should be static, but commands/variable.c needs to get at this */
@@ -4442,6 +4443,17 @@ static struct config_string ConfigureNamesString[] =
44424443
check_backtrace_functions,assign_backtrace_functions,NULL
44434444
},
44444445

4446+
{
4447+
{"restrict_nonsystem_relation_kind",PGC_USERSET,CLIENT_CONN_STATEMENT,
4448+
gettext_noop("Sets relation kinds of non-system relation to restrict use"),
4449+
NULL,
4450+
GUC_LIST_INPUT |GUC_NOT_IN_SAMPLE
4451+
},
4452+
&restrict_nonsystem_relation_kind_string,
4453+
"",
4454+
check_restrict_nonsystem_relation_kind,assign_restrict_nonsystem_relation_kind,NULL
4455+
},
4456+
44454457
/* End-of-list marker */
44464458
{
44474459
{NULL,0,0,NULL,NULL},NULL,NULL,NULL,NULL,NULL

‎src/bin/pg_dump/pg_dump.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
291291
static char *get_synchronized_snapshot(Archive *fout);
292292
static void setupDumpWorker(Archive *AHX);
293293
static TableInfo *getRootTableInfo(TableInfo *tbinfo);
294+
static void set_restrict_relation_kind(Archive *AH, const char *value);
294295
static bool forcePartitionRootLoad(const TableInfo *tbinfo);
295296

296297

@@ -1178,6 +1179,13 @@ setup_connection(Archive *AH, const char *dumpencoding,
11781179
ExecuteSqlStatement(AH, "SET row_security = off");
11791180
}
11801181

1182+
/*
1183+
* For security reasons, we restrict the expansion of non-system views and
1184+
* access to foreign tables during the pg_dump process. This restriction
1185+
* is adjusted when dumping foreign table data.
1186+
*/
1187+
set_restrict_relation_kind(AH, "view, foreign-table");
1188+
11811189
/*
11821190
* Start transaction-snapshot mode transaction to dump consistent data.
11831191
*/
@@ -1900,6 +1908,10 @@ dumpTableData_copy(Archive *fout, void *dcontext)
19001908
*/
19011909
if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
19021910
{
1911+
/* Temporary allows to access to foreign tables to dump data */
1912+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
1913+
set_restrict_relation_kind(fout, "view");
1914+
19031915
/* Note: this syntax is only supported in 8.2 and up */
19041916
appendPQExpBufferStr(q, "COPY (SELECT ");
19051917
/* klugery to get rid of parens in column list */
@@ -2012,6 +2024,11 @@ dumpTableData_copy(Archive *fout, void *dcontext)
20122024
classname);
20132025

20142026
destroyPQExpBuffer(q);
2027+
2028+
/* Revert back the setting */
2029+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2030+
set_restrict_relation_kind(fout, "view, foreign-table");
2031+
20152032
return 1;
20162033
}
20172034

@@ -2038,6 +2055,10 @@ dumpTableData_insert(Archive *fout, void *dcontext)
20382055
introws_per_statement = dopt->dump_inserts;
20392056
introws_this_statement = 0;
20402057

2058+
/* Temporary allows to access to foreign tables to dump data */
2059+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2060+
set_restrict_relation_kind(fout, "view");
2061+
20412062
/*
20422063
* If we're going to emit INSERTs with column names, the most efficient
20432064
* way to deal with generated columns is to exclude them entirely. For
@@ -2277,6 +2298,10 @@ dumpTableData_insert(Archive *fout, void *dcontext)
22772298
destroyPQExpBuffer(insertStmt);
22782299
free(attgenerated);
22792300

2301+
/* Revert back the setting */
2302+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2303+
set_restrict_relation_kind(fout, "view, foreign-table");
2304+
22802305
return 1;
22812306
}
22822307

@@ -4306,6 +4331,28 @@ is_superuser(Archive *fout)
43064331
return false;
43074332
}
43084333

4334+
/*
4335+
* Set the given value to restrict_nonsystem_relation_kind value. Since
4336+
* restrict_nonsystem_relation_kind is introduced in minor version releases,
4337+
* the setting query is effective only where available.
4338+
*/
4339+
static void
4340+
set_restrict_relation_kind(Archive *AH, const char *value)
4341+
{
4342+
PQExpBuffer query = createPQExpBuffer();
4343+
PGresult *res;
4344+
4345+
appendPQExpBuffer(query,
4346+
"SELECT set_config(name, '%s', false) "
4347+
"FROM pg_settings "
4348+
"WHERE name = 'restrict_nonsystem_relation_kind'",
4349+
value);
4350+
res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
4351+
4352+
PQclear(res);
4353+
destroyPQExpBuffer(query);
4354+
}
4355+
43094356
/*
43104357
* getSubscriptions
43114358
* get information about subscriptions

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp