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

Commit6aba85a

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 parentd031106 commit6aba85a

File tree

15 files changed

+255
-1
lines changed

15 files changed

+255
-1
lines changed

‎contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,17 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1;
637637
Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST
638638
(3 rows)
639639

640+
-- test restriction on non-system foreign tables.
641+
SET restrict_nonsystem_relation_kind TO 'foreign-table';
642+
SELECT * from ft1 where c1 < 1; -- ERROR
643+
ERROR: access to non-system foreign table is restricted
644+
INSERT INTO ft1 (c1) VALUES (1); -- ERROR
645+
ERROR: access to non-system foreign table is restricted
646+
DELETE FROM ft1 WHERE c1 = 1; -- ERROR
647+
ERROR: access to non-system foreign table is restricted
648+
TRUNCATE ft1; -- ERROR
649+
ERROR: access to non-system foreign table is restricted
650+
RESET restrict_nonsystem_relation_kind;
640651
-- ===================================================================
641652
-- WHERE with remotely-executable conditions
642653
-- ===================================================================

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ DELETE FROM loct_empty;
327327
ANALYZE ft_empty;
328328
EXPLAIN (VERBOSE, COSTS OFF)SELECT*FROM ft_emptyORDER BY c1;
329329

330+
-- test restriction on non-system foreign tables.
331+
SET restrict_nonsystem_relation_kind TO'foreign-table';
332+
SELECT*from ft1where c1<1;-- ERROR
333+
INSERT INTO ft1 (c1)VALUES (1);-- ERROR
334+
DELETEFROM ft1WHERE c1=1;-- ERROR
335+
TRUNCATE ft1;-- ERROR
336+
RESET restrict_nonsystem_relation_kind;
337+
330338
-- ===================================================================
331339
-- WHERE with remotely-executable conditions
332340
-- ===================================================================

‎doc/src/sgml/config.sgml

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

9567+
<varlistentry id="guc-restrict-nonsystem-relation-kind" xreflabel="restrict_nonsystem_relation_kind">
9568+
<term><varname>restrict_nonsystem_relation_kind</varname> (<type>string</type>)
9569+
<indexterm>
9570+
<primary><varname>restrict_nonsystem_relation_kind</varname></primary>
9571+
<secondary>configuration parameter</secondary>
9572+
</indexterm>
9573+
</term>
9574+
<listitem>
9575+
<para>
9576+
This variable specifies relation kind to which access is restricted.
9577+
It contains a comma-separated list of relation kind. Currently, the
9578+
supported relation kinds are <literal>view</literal> and
9579+
<literal>foreign-table</literal>.
9580+
</para>
9581+
</listitem>
9582+
</varlistentry>
9583+
95679584
</variablelist>
95689585
</sect2>
95699586
<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
@@ -868,6 +868,14 @@ PostgreSQL documentation
868868
The only exception is that an empty pattern is disallowed.
869869
</para>
870870

871+
<note>
872+
<para>
873+
Using wildcards in <option>--include-foreign-data</option> may result
874+
in access to unexpected foreign servers. Also, to use this option securely,
875+
make sure that the named server must have a trusted owner.
876+
</para>
877+
</note>
878+
871879
<note>
872880
<para>
873881
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
@@ -23,6 +23,7 @@
2323
#include"funcapi.h"
2424
#include"lib/stringinfo.h"
2525
#include"miscadmin.h"
26+
#include"tcop/tcopprot.h"
2627
#include"utils/builtins.h"
2728
#include"utils/memutils.h"
2829
#include"utils/rel.h"
@@ -323,6 +324,15 @@ GetFdwRoutine(Oid fdwhandler)
323324
Datumdatum;
324325
FdwRoutine*routine;
325326

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

‎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

@@ -7090,7 +7091,19 @@ make_modifytable(PlannerInfo *root, Plan *subplan,
70907091

70917092
if (rte->rtekind==RTE_RELATION&&
70927093
rte->relkind==RELKIND_FOREIGN_TABLE)
7094+
{
7095+
/* Check if the access to foreign tables is restricted */
7096+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_FOREIGN_TABLE)!=0))
7097+
{
7098+
/* there must not be built-in foreign tables */
7099+
Assert(rte->relid >=FirstNormalObjectId);
7100+
ereport(ERROR,
7101+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
7102+
errmsg("access to non-system foreign table is restricted")));
7103+
}
7104+
70937105
fdwroutine=GetFdwRoutineByRelId(rte->relid);
7106+
}
70947107
else
70957108
fdwroutine=NULL;
70967109
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include"rewrite/rewriteManip.h"
4848
#include"statistics/statistics.h"
4949
#include"storage/bufmgr.h"
50+
#include"tcop/tcopprot.h"
5051
#include"utils/builtins.h"
5152
#include"utils/lsyscache.h"
5253
#include"utils/partcache.h"
@@ -500,6 +501,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
500501
/* Grab foreign-table info using the relcache, while we have it */
501502
if (relation->rd_rel->relkind==RELKIND_FOREIGN_TABLE)
502503
{
504+
/* Check if the access to foreign tables is restricted */
505+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_FOREIGN_TABLE)!=0))
506+
{
507+
/* there must not be built-in foreign tables */
508+
Assert(RelationGetRelid(relation) >=FirstNormalObjectId);
509+
510+
ereport(ERROR,
511+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
512+
errmsg("access to non-system foreign table is restricted")));
513+
}
514+
503515
rel->serverid=GetForeignServerIdByRelId(RelationGetRelid(relation));
504516
rel->fdwroutine=GetFdwRoutineForRelation(relation, true);
505517
}

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include"rewrite/rewriteManip.h"
4242
#include"rewrite/rewriteSearchCycle.h"
4343
#include"rewrite/rowsecurity.h"
44+
#include"tcop/tcopprot.h"
4445
#include"utils/builtins.h"
4546
#include"utils/lsyscache.h"
4647
#include"utils/rel.h"
@@ -1740,6 +1741,14 @@ ApplyRetrieveRule(Query *parsetree,
17401741
if (rule->qual!=NULL)
17411742
elog(ERROR,"cannot handle qualified ON SELECT rule");
17421743

1744+
/* Check if the expansion of non-system views are restricted */
1745+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_VIEW)!=0&&
1746+
RelationGetRelid(relation) >=FirstNormalObjectId))
1747+
ereport(ERROR,
1748+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1749+
errmsg("access to non-system view \"%s\" is restricted",
1750+
RelationGetRelationName(relation))));
1751+
17431752
if (rt_index==parsetree->resultRelation)
17441753
{
17451754
/*
@@ -3108,6 +3117,14 @@ rewriteTargetView(Query *parsetree, Relation view)
31083117
}
31093118
}
31103119

3120+
/* Check if the expansion of non-system views are restricted */
3121+
if (unlikely((restrict_nonsystem_relation_kind&RESTRICT_RELKIND_VIEW)!=0&&
3122+
RelationGetRelid(view) >=FirstNormalObjectId))
3123+
ereport(ERROR,
3124+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3125+
errmsg("access to non-system view \"%s\" is restricted",
3126+
RelationGetRelationName(view))));
3127+
31113128
/*
31123129
* For INSERT/UPDATE the modified columns must all be updatable.
31133130
*/

‎src/backend/tcop/postgres.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#include"utils/snapmgr.h"
7878
#include"utils/timeout.h"
7979
#include"utils/timestamp.h"
80+
#include"utils/varlena.h"
8081

8182
/* ----------------
8283
*global variables
@@ -101,6 +102,9 @@ intPostAuthDelay = 0;
101102
/* Time between checks that the client is still connected. */
102103
intclient_connection_check_interval=0;
103104

105+
/* flags for non-system relation kinds to restrict use */
106+
intrestrict_nonsystem_relation_kind;
107+
104108
/* ----------------
105109
*private typedefs etc
106110
* ----------------
@@ -3628,6 +3632,66 @@ check_log_stats(bool *newval, void **extra, GucSource source)
36283632
return true;
36293633
}
36303634

3635+
/*
3636+
* GUC check_hook for restrict_nonsystem_relation_kind
3637+
*/
3638+
bool
3639+
check_restrict_nonsystem_relation_kind(char**newval,void**extra,GucSourcesource)
3640+
{
3641+
char*rawstring;
3642+
List*elemlist;
3643+
ListCell*l;
3644+
intflags=0;
3645+
3646+
/* Need a modifiable copy of string */
3647+
rawstring=pstrdup(*newval);
3648+
3649+
if (!SplitIdentifierString(rawstring,',',&elemlist))
3650+
{
3651+
/* syntax error in list */
3652+
GUC_check_errdetail("List syntax is invalid.");
3653+
pfree(rawstring);
3654+
list_free(elemlist);
3655+
return false;
3656+
}
3657+
3658+
foreach(l,elemlist)
3659+
{
3660+
char*tok= (char*)lfirst(l);
3661+
3662+
if (pg_strcasecmp(tok,"view")==0)
3663+
flags |=RESTRICT_RELKIND_VIEW;
3664+
elseif (pg_strcasecmp(tok,"foreign-table")==0)
3665+
flags |=RESTRICT_RELKIND_FOREIGN_TABLE;
3666+
else
3667+
{
3668+
GUC_check_errdetail("Unrecognized key word: \"%s\".",tok);
3669+
pfree(rawstring);
3670+
list_free(elemlist);
3671+
return false;
3672+
}
3673+
}
3674+
3675+
pfree(rawstring);
3676+
list_free(elemlist);
3677+
3678+
/* Save the flags in *extra, for use by the assign function */
3679+
*extra=guc_malloc(ERROR,sizeof(int));
3680+
*((int*)*extra)=flags;
3681+
3682+
return true;
3683+
}
3684+
3685+
/*
3686+
* GUC assign_hook for restrict_nonsystem_relation_kind
3687+
*/
3688+
void
3689+
assign_restrict_nonsystem_relation_kind(constchar*newval,void*extra)
3690+
{
3691+
int*flags= (int*)extra;
3692+
3693+
restrict_nonsystem_relation_kind=*flags;
3694+
}
36313695

36323696
/*
36333697
* set_debug_options --- apply "-d N" command line option

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ static char *server_encoding_string;
564564
staticchar*server_version_string;
565565
staticintserver_version_num;
566566
staticchar*debug_io_direct_string;
567+
staticchar*restrict_nonsystem_relation_kind_string;
567568

568569
#ifdefHAVE_SYSLOG
569570
#defineDEFAULT_SYSLOG_FACILITY LOG_LOCAL0
@@ -4549,6 +4550,17 @@ struct config_string ConfigureNamesString[] =
45494550
check_debug_io_direct,assign_debug_io_direct,NULL
45504551
},
45514552

4553+
{
4554+
{"restrict_nonsystem_relation_kind",PGC_USERSET,CLIENT_CONN_STATEMENT,
4555+
gettext_noop("Sets relation kinds of non-system relation to restrict use"),
4556+
NULL,
4557+
GUC_LIST_INPUT |GUC_NOT_IN_SAMPLE
4558+
},
4559+
&restrict_nonsystem_relation_kind_string,
4560+
"",
4561+
check_restrict_nonsystem_relation_kind,assign_restrict_nonsystem_relation_kind,NULL
4562+
},
4563+
45524564
/* End-of-list marker */
45534565
{
45544566
{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
@@ -324,6 +324,7 @@ static bool nonemptyReloptions(const char *reloptions);
324324
static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
325325
const char *prefix, Archive *fout);
326326
static char *get_synchronized_snapshot(Archive *fout);
327+
static void set_restrict_relation_kind(Archive *AH, const char *value);
327328
static void setupDumpWorker(Archive *AH);
328329
static TableInfo *getRootTableInfo(const TableInfo *tbinfo);
329330
static bool forcePartitionRootLoad(const TableInfo *tbinfo);
@@ -1252,6 +1253,13 @@ setup_connection(Archive *AH, const char *dumpencoding,
12521253
ExecuteSqlStatement(AH, "SET row_security = off");
12531254
}
12541255

1256+
/*
1257+
* For security reasons, we restrict the expansion of non-system views and
1258+
* access to foreign tables during the pg_dump process. This restriction
1259+
* is adjusted when dumping foreign table data.
1260+
*/
1261+
set_restrict_relation_kind(AH, "view, foreign-table");
1262+
12551263
/*
12561264
* Initialize prepared-query state to "nothing prepared". We do this here
12571265
* so that a parallel dump worker will have its own state.
@@ -2114,6 +2122,10 @@ dumpTableData_copy(Archive *fout, const void *dcontext)
21142122
*/
21152123
if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
21162124
{
2125+
/* Temporary allows to access to foreign tables to dump data */
2126+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2127+
set_restrict_relation_kind(fout, "view");
2128+
21172129
appendPQExpBufferStr(q, "COPY (SELECT ");
21182130
/* klugery to get rid of parens in column list */
21192131
if (strlen(column_list) > 2)
@@ -2225,6 +2237,11 @@ dumpTableData_copy(Archive *fout, const void *dcontext)
22252237
classname);
22262238

22272239
destroyPQExpBuffer(q);
2240+
2241+
/* Revert back the setting */
2242+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2243+
set_restrict_relation_kind(fout, "view, foreign-table");
2244+
22282245
return 1;
22292246
}
22302247

@@ -2251,6 +2268,10 @@ dumpTableData_insert(Archive *fout, const void *dcontext)
22512268
introws_per_statement = dopt->dump_inserts;
22522269
introws_this_statement = 0;
22532270

2271+
/* Temporary allows to access to foreign tables to dump data */
2272+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2273+
set_restrict_relation_kind(fout, "view");
2274+
22542275
/*
22552276
* If we're going to emit INSERTs with column names, the most efficient
22562277
* way to deal with generated columns is to exclude them entirely. For
@@ -2490,6 +2511,10 @@ dumpTableData_insert(Archive *fout, const void *dcontext)
24902511
destroyPQExpBuffer(insertStmt);
24912512
free(attgenerated);
24922513

2514+
/* Revert back the setting */
2515+
if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
2516+
set_restrict_relation_kind(fout, "view, foreign-table");
2517+
24932518
return 1;
24942519
}
24952520

@@ -4590,6 +4615,28 @@ is_superuser(Archive *fout)
45904615
return false;
45914616
}
45924617

4618+
/*
4619+
* Set the given value to restrict_nonsystem_relation_kind value. Since
4620+
* restrict_nonsystem_relation_kind is introduced in minor version releases,
4621+
* the setting query is effective only where available.
4622+
*/
4623+
static void
4624+
set_restrict_relation_kind(Archive *AH, const char *value)
4625+
{
4626+
PQExpBuffer query = createPQExpBuffer();
4627+
PGresult *res;
4628+
4629+
appendPQExpBuffer(query,
4630+
"SELECT set_config(name, '%s', false) "
4631+
"FROM pg_settings "
4632+
"WHERE name = 'restrict_nonsystem_relation_kind'",
4633+
value);
4634+
res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
4635+
4636+
PQclear(res);
4637+
destroyPQExpBuffer(query);
4638+
}
4639+
45934640
/*
45944641
* getSubscriptions
45954642
* get information about subscriptions

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp