Compare commits

..

No commits in common. "c8-stream-10" and "c8-stream-12" have entirely different histories.

23 changed files with 13581 additions and 1193 deletions

4
.gitignore vendored
View File

@ -1,4 +1,4 @@
SOURCES/postgresql-10.23-US.pdf
SOURCES/postgresql-10.23.tar.bz2
SOURCES/postgresql-9.2.24.tar.bz2
SOURCES/postgresql-12.22-US.pdf
SOURCES/postgresql-12.22.tar.bz2
SOURCES/postgresql-setup-8.7.tar.gz

View File

@ -1,4 +1,4 @@
a416c245ff0815fbde534bc49b0a07ffdd373894 SOURCES/postgresql-10.23-US.pdf
2df7b4b3751112f3cb543c3ea81e45531bebc7a1 SOURCES/postgresql-10.23.tar.bz2
63d6966ccdbab6aae1f9754fdb8e341ada1ef653 SOURCES/postgresql-9.2.24.tar.bz2
e4c99bb52875c4822f4cf4a63dc69d5de1cb8a05 SOURCES/postgresql-12.22-US.pdf
4f0a2bfcdaa6b370029353d7a01451d7a8282750 SOURCES/postgresql-12.22.tar.bz2
fb97095dc9648f9c31d58fcb406831da5e419ddf SOURCES/postgresql-setup-8.7.tar.gz

242
SOURCES/CVE-2025-8715.patch Normal file
View File

@ -0,0 +1,242 @@
From 2179e6005ec9500d5e130f53f7d3ed7c8d4439a9 Mon Sep 17 00:00:00 2001
From: Noah Misch <noah@leadboat.com>
Date: Mon, 11 Aug 2025 06:18:59 -0700
Subject: [PATCH 1/2] Convert newlines to spaces in names written in v11+
pg_dump comments.
Maliciously-crafted object names could achieve SQL injection during
restore. CVE-2012-0868 fixed this class of problem at the time, but
later work reintroduced three cases. Commit
bc8cd50fefd369b217f80078585c486505aafb62 (back-patched to v11+ in
2023-05 releases) introduced the pg_dump case. Commit
6cbdbd9e8d8f2986fde44f2431ed8d0c8fce7f5d (v12+) introduced the two
pg_dumpall cases. Move sanitize_line(), unchanged, to dumputils.c so
pg_dumpall has access to it in all supported versions. Back-patch to
v13 (all supported versions).
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Backpatch-through: 13
Security: CVE-2025-8715
---
src/bin/pg_dump/dumputils.c | 37 ++++++++++++++++++++
src/bin/pg_dump/dumputils.h | 1 +
src/bin/pg_dump/pg_backup_archiver.c | 37 --------------------
src/bin/pg_dump/pg_dump.c | 5 ++-
src/bin/pg_dump/pg_dumpall.c | 11 ++++--
src/bin/pg_dump/t/002_pg_dump.pl | 21 +++++++++++
src/bin/pg_dump/t/003_pg_dump_with_server.pl | 19 ++++++++--
7 files changed, 89 insertions(+), 42 deletions(-)
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 2de0cef40aa..19ed4842f18 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -29,6 +29,43 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
const char *subname);
+/*
+ * Sanitize a string to be included in an SQL comment or TOC listing, by
+ * replacing any newlines with spaces. This ensures each logical output line
+ * is in fact one physical output line, to prevent corruption of the dump
+ * (which could, in the worst case, present an SQL injection vulnerability
+ * if someone were to incautiously load a dump containing objects with
+ * maliciously crafted names).
+ *
+ * The result is a freshly malloc'd string. If the input string is NULL,
+ * return a malloc'ed empty string, unless want_hyphen, in which case return a
+ * malloc'ed hyphen.
+ *
+ * Note that we currently don't bother to quote names, meaning that the name
+ * fields aren't automatically parseable. "pg_restore -L" doesn't care because
+ * it only examines the dumpId field, but someday we might want to try harder.
+ */
+char *
+sanitize_line(const char *str, bool want_hyphen)
+{
+ char *result;
+ char *s;
+
+ if (!str)
+ return pg_strdup(want_hyphen ? "-" : "");
+
+ result = pg_strdup(str);
+
+ for (s = result; *s != '\0'; s++)
+ {
+ if (*s == '\n' || *s == '\r')
+ *s = ' ';
+ }
+
+ return result;
+}
+
+
/*
* Build GRANT/REVOKE command(s) for an object.
*
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index cb1d98d873e..950cdb5f579 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -36,6 +36,7 @@
#endif
+extern char *sanitize_line(const char *str, bool want_hyphen);
extern bool buildACLCommands(const char *name, const char *subname, const char *nspname,
const char *type, const char *acls, const char *racls,
const char *owner, const char *prefix, int remoteVersion,
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 1040b1b6b65..3bbd3cb8880 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -73,7 +73,6 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
ArchiveHandle *AH);
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
-static char *sanitize_line(const char *str, bool want_hyphen);
static void _doSetFixedOutputState(ArchiveHandle *AH);
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
@@ -3719,42 +3718,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
}
}
-/*
- * Sanitize a string to be included in an SQL comment or TOC listing, by
- * replacing any newlines with spaces. This ensures each logical output line
- * is in fact one physical output line, to prevent corruption of the dump
- * (which could, in the worst case, present an SQL injection vulnerability
- * if someone were to incautiously load a dump containing objects with
- * maliciously crafted names).
- *
- * The result is a freshly malloc'd string. If the input string is NULL,
- * return a malloc'ed empty string, unless want_hyphen, in which case return a
- * malloc'ed hyphen.
- *
- * Note that we currently don't bother to quote names, meaning that the name
- * fields aren't automatically parseable. "pg_restore -L" doesn't care because
- * it only examines the dumpId field, but someday we might want to try harder.
- */
-static char *
-sanitize_line(const char *str, bool want_hyphen)
-{
- char *result;
- char *s;
-
- if (!str)
- return pg_strdup(want_hyphen ? "-" : "");
-
- result = pg_strdup(str);
-
- for (s = result; *s != '\0'; s++)
- {
- if (*s == '\n' || *s == '\r')
- *s = ' ';
- }
-
- return result;
-}
-
/*
* Write the file header for a custom-format archive
*/
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 29d37158a38..96aac99a944 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2396,11 +2396,14 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
forcePartitionRootLoad(tbinfo)))
{
TableInfo *parentTbinfo;
+ char *sanitized;
parentTbinfo = getRootTableInfo(tbinfo);
copyFrom = fmtQualifiedDumpable(parentTbinfo);
+ sanitized = sanitize_line(copyFrom, true);
printfPQExpBuffer(copyBuf, "-- load via partition root %s",
- copyFrom);
+ sanitized);
+ free(sanitized);
tdDefn = pg_strdup(copyBuf->data);
}
else
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 41ddc217388..7537922a8f3 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1407,6 +1407,8 @@ dumpUserConfig(PGconn *conn, const char *username)
if (PQntuples(res) == 1 &&
!PQgetisnull(res, 0, 0))
{
+ char *sanitized;
+
/* comment at section start, only if needed */
if (first)
{
@@ -1414,7 +1416,9 @@ dumpUserConfig(PGconn *conn, const char *username)
first = false;
}
- fprintf(OPF, "--\n-- User Config \"%s\"\n--\n\n", username);
+ sanitized = sanitize_line(username, true);
+ fprintf(OPF, "--\n-- User Config \"%s\"\n--\n\n", sanitized);
+ free(sanitized);
resetPQExpBuffer(buf);
makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
"ROLE", username, NULL, NULL,
@@ -1508,6 +1512,7 @@ dumpDatabases(PGconn *conn)
for (i = 0; i < PQntuples(res); i++)
{
char *dbname = PQgetvalue(res, i, 0);
+ char *sanitized;
const char *create_opts;
int ret;
@@ -1524,7 +1529,9 @@ dumpDatabases(PGconn *conn)
pg_log_info("dumping database \"%s\"", dbname);
- fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname);
+ sanitized = sanitize_line(dbname, true);
+ fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", sanitized);
+ free(sanitized);
/*
* We assume that "template1" and "postgres" already exist in the
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 93193c0bd4b..cb83714b017 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -1430,6 +1430,27 @@ my %tests = (
},
},
+ 'newline of role or table name in comment' => {
+ create_sql => qq{CREATE ROLE regress_newline;
+ ALTER ROLE regress_newline SET enable_seqscan = off;
+ ALTER ROLE regress_newline
+ RENAME TO "regress_newline\nattack";
+
+ -- meet getPartitioningInfo() "unsafe" condition
+ CREATE TYPE pp_colors AS
+ ENUM ('green', 'blue', 'black');
+ CREATE TABLE pp_enumpart (a pp_colors)
+ PARTITION BY HASH (a);
+ CREATE TABLE pp_enumpart1 PARTITION OF pp_enumpart
+ FOR VALUES WITH (MODULUS 2, REMAINDER 0);
+ CREATE TABLE pp_enumpart2 PARTITION OF pp_enumpart
+ FOR VALUES WITH (MODULUS 2, REMAINDER 1);
+ ALTER TABLE pp_enumpart
+ RENAME TO "pp_enumpart\nattack";},
+ regexp => qr/\n--[^\n]*\nattack/s,
+ like => {},
+ },
+
'CREATE DATABASE regression_invalid...' => {
create_order => 1,
create_sql => q(
--
2.50.1

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,9 @@ installcheck-parallel: cleandirs
cleandirs:
-rm -rf testtablespace results
mkdir testtablespace results
[ -x /usr/bin/chcon ] && /usr/bin/chcon -u system_u -r object_r -t postgresql_db_t testtablespace results
if test -x /usr/bin/chcon && ! test -f /.dockerenv; then \
/usr/bin/chcon -u system_u -r object_r -t postgresql_db_t testtablespace results ; \
fi
# old interfaces follow...

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +0,0 @@
#! /bin/sh
# This script builds the PDF version of the PostgreSQL documentation.
#
# In principle we could do this as part of the RPM build, but there are
# good reasons not to:
# 1. The build would take longer and have a larger BuildRequires footprint.
# 2. The generated PDF has timestamps in it, which would inevitably result
# in multilib conflicts due to slightly different timestamps.
# So instead, we run this manually when rebasing to a new upstream release,
# and treat the resulting PDF as a separate Source file.
#
# You will need to have the docbook packages installed to run this.
# Expect it to take about 20 minutes and use about 160MB of disk.
set -e
# Pass package version (e.g., 9.1.2) as argument
VERSION=$1
test -z "$VERSION" && VERSION=`awk '/^Version:/ { print $2; }' postgresql.spec`
TARGETFILE=postgresql-$VERSION-US.pdf
test -f "$TARGETFILE" && echo "$TARGETFILE exists" && exit 1
echo Building $TARGETFILE ...
# Unpack postgresql
rm -rf postgresql-$VERSION
tar xfj postgresql-$VERSION.tar.bz2
cd postgresql-$VERSION
# Apply any patches that affect the PDF documentation
# patch -p1 < ../xxx.patch
# Configure ...
./configure >/dev/null
# Build the PDF docs
cd doc/src/sgml
make postgres-US.pdf >make.log
mv -f postgres-US.pdf ../../../../$TARGETFILE
# Clean up
cd ../../../..
rm -rf postgresql-$VERSION
exit 0

View File

@ -1,249 +0,0 @@
From 681d9e4621aac0a9c71364b6f54f00f6d8c4337f Mon Sep 17 00:00:00 2001
From 8d525d7b9545884a3e0d79adcd61543f9ae2ae28 Mon Sep 17 00:00:00 2001
From: Noah Misch <noah@leadboat.com>
Date: Mon, 8 May 2023 06:14:07 -0700
Subject: Replace last PushOverrideSearchPath() call with
set_config_option().
The two methods don't cooperate, so set_config_option("search_path",
...) has been ineffective under non-empty overrideStack. This defect
enabled an attacker having database-level CREATE privilege to execute
arbitrary code as the bootstrap superuser. While that particular attack
requires v13+ for the trusted extension attribute, other attacks are
feasible in all supported versions.
Standardize on the combination of NewGUCNestLevel() and
set_config_option("search_path", ...). It is newer than
PushOverrideSearchPath(), more-prevalent, and has no known
disadvantages. The "override" mechanism remains for now, for
compatibility with out-of-tree code. Users should update such code,
which likely suffers from the same sort of vulnerability closed here.
Back-patch to v11 (all supported versions).
Alexander Lakhin. Reported by Alexander Lakhin.
Security: CVE-2023-2454
---
contrib/seg/Makefile | 2 +-
contrib/seg/expected/security.out | 32 ++++++++++++++++++
contrib/seg/sql/security.sql | 32 ++++++++++++++++++
src/backend/catalog/namespace.c | 4 +++
src/backend/commands/schemacmds.c | 37 ++++++++++++++------
src/test/regress/expected/namespace.out | 45 +++++++++++++++++++++++++
src/test/regress/sql/namespace.sql | 24 +++++++++++++
7 files changed, 165 insertions(+), 11 deletions(-)
create mode 100644 contrib/seg/expected/security.out
create mode 100644 contrib/seg/sql/security.sql
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 14e57adee2..73ddb67882 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3515,6 +3515,10 @@ OverrideSearchPathMatchesCurrent(OverrideSearchPath *path)
/*
* PushOverrideSearchPath - temporarily override the search path
*
+ * Do not use this function; almost any usage introduces a security
+ * vulnerability. It exists for the benefit of legacy code running in
+ * non-security-sensitive environments.
+ *
* We allow nested overrides, hence the push/pop terminology. The GUC
* search_path variable is ignored while an override is active.
*
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 48590247f8..b6a71154a8 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -30,6 +30,7 @@
#include "commands/schemacmds.h"
#include "miscadmin.h"
#include "parser/parse_utilcmd.h"
+#include "parser/scansup.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
@@ -53,14 +54,16 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
{
const char *schemaName = stmt->schemaname;
Oid namespaceId;
- OverrideSearchPath *overridePath;
List *parsetree_list;
ListCell *parsetree_item;
Oid owner_uid;
Oid saved_uid;
int save_sec_context;
+ int save_nestlevel;
+ char *nsp = namespace_search_path;
AclResult aclresult;
ObjectAddress address;
+ StringInfoData pathbuf;
GetUserIdAndSecContext(&saved_uid, &save_sec_context);
@@ -153,14 +156,26 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
CommandCounterIncrement();
/*
- * Temporarily make the new namespace be the front of the search path, as
- * well as the default creation target namespace. This will be undone at
- * the end of this routine, or upon error.
+ * Prepend the new schema to the current search path.
+ *
+ * We use the equivalent of a function SET option to allow the setting to
+ * persist for exactly the duration of the schema creation. guc.c also
+ * takes care of undoing the setting on error.
*/
- overridePath = GetOverrideSearchPath(CurrentMemoryContext);
- overridePath->schemas = lcons_oid(namespaceId, overridePath->schemas);
- /* XXX should we clear overridePath->useTemp? */
- PushOverrideSearchPath(overridePath);
+ save_nestlevel = NewGUCNestLevel();
+
+ initStringInfo(&pathbuf);
+ appendStringInfoString(&pathbuf, quote_identifier(schemaName));
+
+ while (scanner_isspace(*nsp))
+ nsp++;
+
+ if (*nsp != '\0')
+ appendStringInfo(&pathbuf, ", %s", nsp);
+
+ (void) set_config_option("search_path", pathbuf.data,
+ PGC_USERSET, PGC_S_SESSION,
+ GUC_ACTION_SAVE, true, 0, false);
/*
* Report the new schema to possibly interested event triggers. Note we
@@ -215,8 +230,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
CommandCounterIncrement();
}
- /* Reset search path to normal state */
- PopOverrideSearchPath();
+ /*
+ * Restore the GUC variable search_path we set above.
+ */
+ AtEOXact_GUC(true, save_nestlevel);
/* Reset current user and security context */
SetUserIdAndSecContext(saved_uid, save_sec_context);
diff --git a/src/test/regress/expected/namespace.out b/src/test/regress/expected/namespace.out
index 2564d1b080..a62fd8ded0 100644
--- a/src/test/regress/expected/namespace.out
+++ b/src/test/regress/expected/namespace.out
@@ -1,6 +1,14 @@
--
-- Regression tests for schemas (namespaces)
--
+-- set the whitespace-only search_path to test that the
+-- GUC list syntax is preserved during a schema creation
+SELECT pg_catalog.set_config('search_path', ' ', false);
+ set_config
+------------
+
+(1 row)
+
CREATE SCHEMA test_schema_1
CREATE UNIQUE INDEX abc_a_idx ON abc (a)
CREATE VIEW abc_view AS
@@ -9,6 +17,43 @@ CREATE SCHEMA test_schema_1
a serial,
b int UNIQUE
);
+-- verify that the correct search_path restored on abort
+SET search_path to public;
+BEGIN;
+SET search_path to public, test_schema_1;
+CREATE SCHEMA test_schema_2
+ CREATE VIEW abc_view AS SELECT c FROM abc;
+ERROR: column "c" does not exist
+LINE 2: CREATE VIEW abc_view AS SELECT c FROM abc;
+ ^
+COMMIT;
+SHOW search_path;
+ search_path
+-------------
+ public
+(1 row)
+
+-- verify that the correct search_path preserved
+-- after creating the schema and on commit
+BEGIN;
+SET search_path to public, test_schema_1;
+CREATE SCHEMA test_schema_2
+ CREATE VIEW abc_view AS SELECT a FROM abc;
+SHOW search_path;
+ search_path
+-----------------------
+ public, test_schema_1
+(1 row)
+
+COMMIT;
+SHOW search_path;
+ search_path
+-----------------------
+ public, test_schema_1
+(1 row)
+
+DROP SCHEMA test_schema_2 CASCADE;
+NOTICE: drop cascades to view test_schema_2.abc_view
-- verify that the objects were created
SELECT COUNT(*) FROM pg_class WHERE relnamespace =
(SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
diff --git a/src/test/regress/sql/namespace.sql b/src/test/regress/sql/namespace.sql
index 6b12c96193..3474f5ecf4 100644
--- a/src/test/regress/sql/namespace.sql
+++ b/src/test/regress/sql/namespace.sql
@@ -2,6 +2,10 @@
-- Regression tests for schemas (namespaces)
--
+-- set the whitespace-only search_path to test that the
+-- GUC list syntax is preserved during a schema creation
+SELECT pg_catalog.set_config('search_path', ' ', false);
+
CREATE SCHEMA test_schema_1
CREATE UNIQUE INDEX abc_a_idx ON abc (a)
@@ -13,6 +17,26 @@ CREATE SCHEMA test_schema_1
b int UNIQUE
);
+-- verify that the correct search_path restored on abort
+SET search_path to public;
+BEGIN;
+SET search_path to public, test_schema_1;
+CREATE SCHEMA test_schema_2
+ CREATE VIEW abc_view AS SELECT c FROM abc;
+COMMIT;
+SHOW search_path;
+
+-- verify that the correct search_path preserved
+-- after creating the schema and on commit
+BEGIN;
+SET search_path to public, test_schema_1;
+CREATE SCHEMA test_schema_2
+ CREATE VIEW abc_view AS SELECT a FROM abc;
+SHOW search_path;
+COMMIT;
+SHOW search_path;
+DROP SCHEMA test_schema_2 CASCADE;
+
-- verify that the objects were created
SELECT COUNT(*) FROM pg_class WHERE relnamespace =
(SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
diff --git a/contrib/sepgsql/expected/ddl.out b/contrib/sepgsql/expected/ddl.out
index e8da587564..15d2b9c5e7 100644
--- a/contrib/sepgsql/expected/ddl.out
+++ b/contrib/sepgsql/expected/ddl.out
@@ -24,7 +24,6 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_reg
CREATE USER regress_sepgsql_test_user;
CREATE SCHEMA regtest_schema;
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema"
-LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="public"
GRANT ALL ON SCHEMA regtest_schema TO regress_sepgsql_test_user;
SET search_path = regtest_schema, public;
CREATE TABLE regtest_table (x serial primary key, y text);
--
2.41.0

View File

@ -1,114 +0,0 @@
From ca73753b090c33bc69ce299b4d7fff891a77b8ad Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 8 May 2023 10:12:44 -0400
Subject: Handle RLS dependencies in inlined set-returning
functions properly.
If an SRF in the FROM clause references a table having row-level
security policies, and we inline that SRF into the calling query,
we neglected to mark the plan as potentially dependent on which
role is executing it. This could lead to later executions in the
same session returning or hiding rows that should have been hidden
or returned instead.
Our thanks to Wolfgang Walther for reporting this problem.
Stephen Frost and Tom Lane
Security: CVE-2023-2455
---
src/backend/optimizer/util/clauses.c | 7 ++++++
src/test/regress/expected/rowsecurity.out | 27 +++++++++++++++++++++++
src/test/regress/sql/rowsecurity.sql | 20 +++++++++++++++++
3 files changed, 54 insertions(+)
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index a9c7bc342e..11269fee3e 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -5205,6 +5205,13 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
*/
record_plan_function_dependency(root, func_oid);
+ /*
+ * We must also notice if the inserted query adds a dependency on the
+ * calling role due to RLS quals.
+ */
+ if (querytree->hasRowSecurity)
+ root->glob->dependsOnRole = true;
+
return querytree;
/* Here if func is not inlinable: release temp memory and return NULL */
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 38f53ed486..e278346420 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -4427,6 +4427,33 @@ SELECT * FROM rls_tbl;
DROP TABLE rls_tbl;
RESET SESSION AUTHORIZATION;
+-- CVE-2023-2455: inlining an SRF may introduce an RLS dependency
+create table rls_t (c text);
+insert into rls_t values ('invisible to bob');
+alter table rls_t enable row level security;
+grant select on rls_t to regress_rls_alice, regress_rls_bob;
+create policy p1 on rls_t for select to regress_rls_alice using (true);
+create policy p2 on rls_t for select to regress_rls_bob using (false);
+create function rls_f () returns setof rls_t
+ stable language sql
+ as $$ select * from rls_t $$;
+prepare q as select current_user, * from rls_f();
+set role regress_rls_alice;
+execute q;
+ current_user | c
+-------------------+------------------
+ regress_rls_alice | invisible to bob
+(1 row)
+
+set role regress_rls_bob;
+execute q;
+ current_user | c
+--------------+---
+(0 rows)
+
+RESET ROLE;
+DROP FUNCTION rls_f();
+DROP TABLE rls_t;
--
-- Clean up objects
--
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index 0fd0cded7d..3d664538a6 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -2127,6 +2127,26 @@ SELECT * FROM rls_tbl;
DROP TABLE rls_tbl;
RESET SESSION AUTHORIZATION;
+-- CVE-2023-2455: inlining an SRF may introduce an RLS dependency
+create table rls_t (c text);
+insert into rls_t values ('invisible to bob');
+alter table rls_t enable row level security;
+grant select on rls_t to regress_rls_alice, regress_rls_bob;
+create policy p1 on rls_t for select to regress_rls_alice using (true);
+create policy p2 on rls_t for select to regress_rls_bob using (false);
+create function rls_f () returns setof rls_t
+ stable language sql
+ as $$ select * from rls_t $$;
+prepare q as select current_user, * from rls_f();
+set role regress_rls_alice;
+execute q;
+set role regress_rls_bob;
+execute q;
+
+RESET ROLE;
+DROP FUNCTION rls_f();
+DROP TABLE rls_t;
+
--
-- Clean up objects
--
--
2.41.0

View File

@ -1,576 +0,0 @@
From d267cea24ea346c739c85bf7bccbd8e8f59da6b3 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 6 Nov 2023 10:56:43 -0500
Subject: [PATCH 1/1] Detect integer overflow while computing new array
dimensions.
array_set_element() and related functions allow an array to be
enlarged by assigning to subscripts outside the current array bounds.
While these places were careful to check that the new bounds are
allowable, they neglected to consider the risk of integer overflow
in computing the new bounds. In edge cases, we could compute new
bounds that are invalid but get past the subsequent checks,
allowing bad things to happen. Memory stomps that are potentially
exploitable for arbitrary code execution are possible, and so is
disclosure of server memory.
To fix, perform the hazardous computations using overflow-detecting
arithmetic routines, which fortunately exist in all still-supported
branches.
The test cases added for this generate (after patching) errors that
mention the value of MaxArraySize, which is platform-dependent.
Rather than introduce multiple expected-files, use psql's VERBOSITY
parameter to suppress the printing of the message text. v11 psql
lacks that parameter, so omit the tests in that branch.
Our thanks to Pedro Gallegos for reporting this problem.
Security: CVE-2023-5869
Sign-Off-By: Tianyue Lan <tianyue.lan@oracle.com>
---
src/backend/utils/adt/arrayfuncs.c | 85 ++++++++++++++++++++++------
src/backend/utils/adt/arrayutils.c | 6 --
src/include/utils/array.h | 7 +++
src/test/regress/expected/arrays.out | 17 ++++++
src/test/regress/sql/arrays.sql | 19 +++++++
src/include/common/int.h | 273 +++++++++++++++++++++++++++++++++++++++
create mode 100644 src/include/common/int.h
6 files changed, 383 insertions(+), 24 deletions(-)
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 553c517..7363893 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -22,6 +22,7 @@
#include "access/htup_details.h"
#include "catalog/pg_type.h"
+#include "common/int.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
@@ -2309,22 +2310,38 @@ array_set_element(Datum arraydatum,
addedbefore = addedafter = 0;
/*
- * Check subscripts
+ * Check subscripts. We assume the existing subscripts passed
+ * ArrayCheckBounds, so that dim[i] + lb[i] can be computed without
+ * overflow. But we must beware of other overflows in our calculations of
+ * new dim[] values.
*/
if (ndim == 1)
{
if (indx[0] < lb[0])
{
- addedbefore = lb[0] - indx[0];
- dim[0] += addedbefore;
+ /* addedbefore = lb[0] - indx[0]; */
+ /* dim[0] += addedbefore; */
+ if (pg_sub_s32_overflow(lb[0], indx[0], &addedbefore) ||
+ pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
lb[0] = indx[0];
if (addedbefore > 1)
newhasnulls = true; /* will insert nulls */
}
if (indx[0] >= (dim[0] + lb[0]))
{
- addedafter = indx[0] - (dim[0] + lb[0]) + 1;
- dim[0] += addedafter;
+ /* addedafter = indx[0] - (dim[0] + lb[0]) + 1; */
+ /* dim[0] += addedafter; */
+ if (pg_sub_s32_overflow(indx[0], dim[0] + lb[0], &addedafter) ||
+ pg_add_s32_overflow(addedafter, 1, &addedafter) ||
+ pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
if (addedafter > 1)
newhasnulls = true; /* will insert nulls */
}
@@ -2568,14 +2585,23 @@ array_set_element_expanded(Datum arraydatum,
addedbefore = addedafter = 0;
/*
- * Check subscripts (this logic matches original array_set_element)
+ * Check subscripts (this logic must match array_set_element). We assume
+ * the existing subscripts passed ArrayCheckBounds, so that dim[i] + lb[i]
+ * can be computed without overflow. But we must beware of other
+ * overflows in our calculations of new dim[] values.
*/
if (ndim == 1)
{
if (indx[0] < lb[0])
{
- addedbefore = lb[0] - indx[0];
- dim[0] += addedbefore;
+ /* addedbefore = lb[0] - indx[0]; */
+ /* dim[0] += addedbefore; */
+ if (pg_sub_s32_overflow(lb[0], indx[0], &addedbefore) ||
+ pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
lb[0] = indx[0];
dimschanged = true;
if (addedbefore > 1)
@@ -2583,8 +2609,15 @@ array_set_element_expanded(Datum arraydatum,
}
if (indx[0] >= (dim[0] + lb[0]))
{
- addedafter = indx[0] - (dim[0] + lb[0]) + 1;
- dim[0] += addedafter;
+ /* addedafter = indx[0] - (dim[0] + lb[0]) + 1; */
+ /* dim[0] += addedafter; */
+ if (pg_sub_s32_overflow(indx[0], dim[0] + lb[0], &addedafter) ||
+ pg_add_s32_overflow(addedafter, 1, &addedafter) ||
+ pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
dimschanged = true;
if (addedafter > 1)
newhasnulls = true; /* will insert nulls */
@@ -2866,7 +2899,10 @@ array_set_slice(Datum arraydatum,
addedbefore = addedafter = 0;
/*
- * Check subscripts
+ * Check subscripts. We assume the existing subscripts passed
+ * ArrayCheckBounds, so that dim[i] + lb[i] can be computed without
+ * overflow. But we must beware of other overflows in our calculations of
+ * new dim[] values.
*/
if (ndim == 1)
{
@@ -2881,18 +2917,31 @@ array_set_slice(Datum arraydatum,
errmsg("upper bound cannot be less than lower bound")));
if (lowerIndx[0] < lb[0])
{
- if (upperIndx[0] < lb[0] - 1)
- newhasnulls = true; /* will insert nulls */
- addedbefore = lb[0] - lowerIndx[0];
- dim[0] += addedbefore;
+ /* addedbefore = lb[0] - lowerIndx[0]; */
+ /* dim[0] += addedbefore; */
+ if (pg_sub_s32_overflow(lb[0], lowerIndx[0], &addedbefore) ||
+ pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
lb[0] = lowerIndx[0];
+ if (addedbefore > 1)
+ newhasnulls = true; /* will insert nulls */
}
if (upperIndx[0] >= (dim[0] + lb[0]))
{
- if (lowerIndx[0] > (dim[0] + lb[0]))
+ /* addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1; */
+ /* dim[0] += addedafter; */
+ if (pg_sub_s32_overflow(upperIndx[0], dim[0] + lb[0], &addedafter) ||
+ pg_add_s32_overflow(addedafter, 1, &addedafter) ||
+ pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array size exceeds the maximum allowed (%d)",
+ (int) MaxArraySize)));
+ if (addedafter > 1)
newhasnulls = true; /* will insert nulls */
- addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
- dim[0] += addedafter;
}
}
else
diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c
index f7c6a51..eb5f2a0 100644
--- a/src/backend/utils/adt/arrayutils.c
+++ b/src/backend/utils/adt/arrayutils.c
@@ -63,10 +63,6 @@ ArrayGetOffset0(int n, const int *tup, const int *scale)
* This must do overflow checking, since it is used to validate that a user
* dimensionality request doesn't overflow what we can handle.
*
- * We limit array sizes to at most about a quarter billion elements,
- * so that it's not necessary to check for overflow in quite so many
- * places --- for instance when palloc'ing Datum arrays.
- *
* The multiplication overflow check only works on machines that have int64
* arithmetic, but that is nearly all platforms these days, and doing check
* divides for those that don't seems way too expensive.
@@ -77,8 +73,6 @@ ArrayGetNItems(int ndim, const int *dims)
int32 ret;
int i;
-#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
-
if (ndim <= 0)
return 0;
ret = 1;
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 905f6b0..3e4c09d 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -65,6 +65,13 @@
#include "utils/expandeddatum.h"
+/*
+ * Maximum number of elements in an array. We limit this to at most about a
+ * quarter billion elements, so that it's not necessary to check for overflow
+ * in quite so many places --- for instance when palloc'ing Datum arrays.
+ */
+#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
+
/*
* Arrays are varlena objects, so must meet the varlena convention that
* the first int32 of the object contains the total object size in bytes.
diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index c730563..e4ec394 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -1347,6 +1347,23 @@ insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk)
-- then you didn't get an indexscan plan, and something is busted.
reset enable_seqscan;
reset enable_bitmapscan;
+-- test subscript overflow detection
+-- The normal error message includes a platform-dependent limit,
+-- so suppress it to avoid needing multiple expected-files.
+\set VERBOSITY terse
+insert into arr_pk_tbl values(10, '[-2147483648:-2147483647]={1,2}');
+update arr_pk_tbl set f1[2147483647] = 42 where pk = 10;
+ERROR: array size exceeds the maximum allowed (134217727)
+update arr_pk_tbl set f1[2147483646:2147483647] = array[4,2] where pk = 10;
+ERROR: array size exceeds the maximum allowed (134217727)
+-- also exercise the expanded-array case
+do $$ declare a int[];
+begin
+ a := '[-2147483648:-2147483647]={1,2}'::int[];
+ a[2147483647] := 42;
+end $$;
+ERROR: array size exceeds the maximum allowed (134217727)
+\set VERBOSITY default
-- test [not] (like|ilike) (any|all) (...)
select 'foo' like any (array['%a', '%o']); -- t
?column?
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 25dd4e2..4ad6e55 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -407,6 +407,25 @@ insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk)
reset enable_seqscan;
reset enable_bitmapscan;
+-- test subscript overflow detection
+
+-- The normal error message includes a platform-dependent limit,
+-- so suppress it to avoid needing multiple expected-files.
+\set VERBOSITY terse
+
+insert into arr_pk_tbl values(10, '[-2147483648:-2147483647]={1,2}');
+update arr_pk_tbl set f1[2147483647] = 42 where pk = 10;
+update arr_pk_tbl set f1[2147483646:2147483647] = array[4,2] where pk = 10;
+
+-- also exercise the expanded-array case
+do $$ declare a int[];
+begin
+ a := '[-2147483648:-2147483647]={1,2}'::int[];
+ a[2147483647] := 42;
+end $$;
+
+\set VERBOSITY default
+
-- test [not] (like|ilike) (any|all) (...)
select 'foo' like any (array['%a', '%o']); -- t
select 'foo' like any (array['%a', '%b']); -- f
diff --git a/src/include/common/int.h b/src/include/common/int.h
new file mode 100644
index 0000000..d754798
--- /dev/null
+++ b/src/include/common/int.h
@@ -0,0 +1,273 @@
+/*-------------------------------------------------------------------------
+ *
+ * int.h
+ * Routines to perform integer math, while checking for overflows.
+ *
+ * The routines in this file are intended to be well defined C, without
+ * relying on compiler flags like -fwrapv.
+ *
+ * To reduce the overhead of these routines try to use compiler intrinsics
+ * where available. That's not that important for the 16, 32 bit cases, but
+ * the 64 bit cases can be considerably faster with intrinsics. In case no
+ * intrinsics are available 128 bit math is used where available.
+ *
+ * Copyright (c) 2017-2019, PostgreSQL Global Development Group
+ *
+ * src/include/common/int.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef COMMON_INT_H
+#define COMMON_INT_H
+
+/*
+ * If a + b overflows, return true, otherwise store the result of a + b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_add_s16_overflow(int16 a, int16 b, int16 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_add_overflow(a, b, result);
+#else
+ int32 res = (int32) a + (int32) b;
+
+ if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int16) res;
+ return false;
+#endif
+}
+
+/*
+ * If a - b overflows, return true, otherwise store the result of a - b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_sub_overflow(a, b, result);
+#else
+ int32 res = (int32) a - (int32) b;
+
+ if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int16) res;
+ return false;
+#endif
+}
+
+/*
+ * If a * b overflows, return true, otherwise store the result of a * b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_mul_overflow(a, b, result);
+#else
+ int32 res = (int32) a * (int32) b;
+
+ if (res > PG_INT16_MAX || res < PG_INT16_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int16) res;
+ return false;
+#endif
+}
+
+/*
+ * If a + b overflows, return true, otherwise store the result of a + b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_add_s32_overflow(int32 a, int32 b, int32 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_add_overflow(a, b, result);
+#else
+ int64 res = (int64) a + (int64) b;
+
+ if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int32) res;
+ return false;
+#endif
+}
+
+/*
+ * If a - b overflows, return true, otherwise store the result of a - b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_sub_overflow(a, b, result);
+#else
+ int64 res = (int64) a - (int64) b;
+
+ if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int32) res;
+ return false;
+#endif
+}
+
+/*
+ * If a * b overflows, return true, otherwise store the result of a * b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_mul_overflow(a, b, result);
+#else
+ int64 res = (int64) a * (int64) b;
+
+ if (res > PG_INT32_MAX || res < PG_INT32_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int32) res;
+ return false;
+#endif
+}
+
+/*
+ * If a + b overflows, return true, otherwise store the result of a + b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_add_s64_overflow(int64 a, int64 b, int64 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_add_overflow(a, b, result);
+#elif defined(HAVE_INT128)
+ int128 res = (int128) a + (int128) b;
+
+ if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int64) res;
+ return false;
+#else
+ if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
+ (a < 0 && b < 0 && a < PG_INT64_MIN - b))
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = a + b;
+ return false;
+#endif
+}
+
+/*
+ * If a - b overflows, return true, otherwise store the result of a - b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_sub_overflow(a, b, result);
+#elif defined(HAVE_INT128)
+ int128 res = (int128) a - (int128) b;
+
+ if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int64) res;
+ return false;
+#else
+ if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
+ (a > 0 && b < 0 && a > PG_INT64_MAX + b))
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = a - b;
+ return false;
+#endif
+}
+
+/*
+ * If a * b overflows, return true, otherwise store the result of a * b into
+ * *result. The content of *result is implementation defined in case of
+ * overflow.
+ */
+static inline bool
+pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_mul_overflow(a, b, result);
+#elif defined(HAVE_INT128)
+ int128 res = (int128) a * (int128) b;
+
+ if (res > PG_INT64_MAX || res < PG_INT64_MIN)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = (int64) res;
+ return false;
+#else
+ /*
+ * Overflow can only happen if at least one value is outside the range
+ * sqrt(min)..sqrt(max) so check that first as the division can be quite a
+ * bit more expensive than the multiplication.
+ *
+ * Multiplying by 0 or 1 can't overflow of course and checking for 0
+ * separately avoids any risk of dividing by 0. Be careful about dividing
+ * INT_MIN by -1 also, note reversing the a and b to ensure we're always
+ * dividing it by a positive value.
+ *
+ */
+ if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||
+ b > PG_INT32_MAX || b < PG_INT32_MIN) &&
+ a != 0 && a != 1 && b != 0 && b != 1 &&
+ ((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||
+ (a > 0 && b < 0 && b < PG_INT64_MIN / a) ||
+ (a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
+ (a < 0 && b < 0 && a < PG_INT64_MAX / b)))
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = a * b;
+ return false;
+#endif
+}
+
+#endif /* COMMON_INT_H */
--
2.39.3

View File

@ -0,0 +1 @@
8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b postgresql-12.22.tar.bz2

View File

@ -1 +0,0 @@
a754c02f7051c2f21e52f8669a421b50485afcde9a581674d6106326b189d126 postgresql-9.2.24.tar.bz2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
From 9923bac72843cd02938868b59284cae16ae24183 Mon Sep 17 00:00:00 2001
From: Petr Khartskhaev <pkhartsk@redhat.com>
Date: Thu, 4 Jun 2026 16:01:59 +0200
Subject: [PATCH] Prevent path traversal in pg_basebackup and pg_rewind
pg_rewind and pg_basebackup could be fed paths from rogue endpoints that
could overwrite the contents of the client when received, achieving path
traversal.
There were two areas in the tree that were sensitive to this problem:
- pg_basebackup, through the astreamer code, where no validation was
performed before building an output path when streaming tar data. This
is an issue in v15 and newer versions.
- pg_rewind file operations for paths received through libpq, for all
the stable branches supported.
In order to address this problem, this commit adds a helper function in
path.c, that reuses path_is_relative_and_below_cwd() after applying
canonicalize_path(). This can be used to validate the paths received
from a connection point. A path is considered invalid if any of the two
following conditions is satisfied:
- The path is absolute.
- The path includes a direct parent-directory reference.
Reported-by: XlabAI Team of Tencent Xuanwu Lab
Reported-by: Valery Gubanov <valerygubanov95@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6475
---
src/bin/pg_rewind/file_ops.c | 23 +++++++++++++++++++++++
src/include/port.h | 1 +
src/port/path.c | 17 +++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index f9e41b1..9b218a4 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -43,6 +43,9 @@ open_target_file(const char *path, bool trunc)
{
int mode;
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for open: \"%s\"", path);
+
if (dry_run)
return;
@@ -173,6 +176,9 @@ remove_target_file(const char *path, bool missing_ok)
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for removal: \"%s\"", path);
+
if (dry_run)
return;
@@ -193,6 +199,9 @@ truncate_target_file(const char *path, off_t newsize)
char dstpath[MAXPGPATH];
int fd;
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for truncation: \"%s\"", path);
+
if (dry_run)
return;
@@ -215,6 +224,10 @@ create_target_dir(const char *path)
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target directory path is unsafe for directory creation: \"%s\"",
+ path);
+
if (dry_run)
return;
@@ -229,6 +242,10 @@ remove_target_dir(const char *path)
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target directory path is unsafe for directory removal: \"%s\"",
+ path);
+
if (dry_run)
return;
@@ -243,6 +260,9 @@ create_target_symlink(const char *path, const char *link)
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target symlink path is unsafe for creation: \"%s\"", path);
+
if (dry_run)
return;
@@ -257,6 +277,9 @@ remove_target_symlink(const char *path)
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target symlink path is unsafe for removal: \"%s\"", path);
+
if (dry_run)
return;
diff --git a/src/include/port.h b/src/include/port.h
index 32925ad..21a8f8a 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -54,6 +54,7 @@ extern void make_native_path(char *path);
extern void cleanup_path(char *path);
extern bool path_contains_parent_reference(const char *path);
extern bool path_is_relative_and_below_cwd(const char *path);
+extern bool path_is_safe_for_extraction(const char *path);
extern bool path_is_prefix_of_path(const char *path1, const char *path2);
extern char *make_absolute_path(const char *path);
extern const char *get_progname(const char *argv0);
diff --git a/src/port/path.c b/src/port/path.c
index 710988b..db30842 100644
--- a/src/port/path.c
+++ b/src/port/path.c
@@ -428,6 +428,23 @@ path_is_relative_and_below_cwd(const char *path)
return true;
}
+/*
+ * Detect whether a path is safe for use during archive extraction.
+ *
+ * This applies canonicalize_path(), then it checks that the path does
+ * not contain any parent directory references.
+ */
+bool
+path_is_safe_for_extraction(const char *path)
+{
+ char buf[MAXPGPATH];
+
+ strlcpy(buf, path, sizeof(buf));
+ canonicalize_path(buf);
+
+ return path_is_relative_and_below_cwd(buf);
+}
+
/*
* Detect whether path1 is a prefix of path2 (including equality).
*
--
2.54.0

View File

@ -0,0 +1,222 @@
From 7174222c87a07fbc0423f2b9bde3cea2cada311c Mon Sep 17 00:00:00 2001
From: Petr Khartskhaev <pkhartsk@redhat.com>
Date: Thu, 4 Jun 2026 16:01:38 +0200
Subject: [PATCH] fix CVE-2026-6477
---
doc/src/sgml/libpq.sgml | 11 ++++++++---
src/interfaces/libpq/fe-exec.c | 18 ++++++++++++++++--
src/interfaces/libpq/fe-lobj.c | 12 ++++++------
src/interfaces/libpq/fe-protocol2.c | 16 +++++++++++++++-
src/interfaces/libpq/fe-protocol3.c | 14 +++++++++++++-
src/interfaces/libpq/libpq-int.h | 9 +++++++--
6 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index cda4e8d..3e87183 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -5272,15 +5272,20 @@ int PQrequestCancel(PGconn *conn);
to send simple function calls to the server.
</para>
- <tip>
+ <warning>
<para>
- This interface is somewhat obsolete, as one can achieve similar
+ This interface is unsafe and should not be used. When
+ <parameter>result_is_int</parameter> is set to <literal>0</literal>,
+ <function>PQfn</function> may write data beyond the end of
+ <parameter>result_buf</parameter>, regardless of whether the buffer has
+ enough space for the requested number of bytes. Furthermore, it is
+ obsolete, as one can achieve similar
performance and greater functionality by setting up a prepared
statement to define the function call. Then, executing the statement
with binary transmission of parameters and results substitutes for a
fast-path function call.
</para>
- </tip>
+ </warning>
<para>
The function <function>PQfn</function><indexterm><primary>PQfn</primary></indexterm>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index ff101c4..5dea7e7 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -2661,6 +2661,20 @@ PQfn(PGconn *conn,
int result_is_int,
const PQArgBlock *args,
int nargs)
+{
+ return PQnfn(conn, fnid, result_buf, -1, result_len,
+ result_is_int, args, nargs);
+}
+
+/*
+ * PQnfn
+ * Private version of PQfn() with verification that returned data fits in
+ * result_buf when result_is_int == 0. Setting buf_size to -1 disables
+ * this verification.
+ */
+PGresult *
+PQnfn(PGconn *conn, int fnid, int *result_buf, int buf_size, int *result_len,
+ int result_is_int, const PQArgBlock *args, int nargs)
{
*result_len = 0;
@@ -2680,12 +2694,12 @@ PQfn(PGconn *conn,
if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
return pqFunctionCall3(conn, fnid,
- result_buf, result_len,
+ result_buf, buf_size, result_len,
result_is_int,
args, nargs);
else
return pqFunctionCall2(conn, fnid,
- result_buf, result_len,
+ result_buf, buf_size, result_len,
result_is_int,
args, nargs);
}
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 6866d64..b019b9e 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -288,8 +288,8 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
argv[1].len = 4;
argv[1].u.integer = (int) len;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
- (void *) buf, &result_len, 0, argv, 2);
+ res = PQnfn(conn, conn->lobjfuncs->fn_lo_read,
+ (void *) buf, len, &result_len, 0, argv, 2);
if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
PQclear(res);
@@ -439,8 +439,8 @@ lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
argv[2].len = 4;
argv[2].u.integer = whence;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
- (void *) &retval, &result_len, 0, argv, 3);
+ res = PQnfn(conn, conn->lobjfuncs->fn_lo_lseek64,
+ (void *) &retval, sizeof(retval), &result_len, 0, argv, 3);
if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
{
PQclear(res);
@@ -605,8 +605,8 @@ lo_tell64(PGconn *conn, int fd)
argv[0].len = 4;
argv[0].u.integer = fd;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
- (void *) &retval, &result_len, 0, argv, 1);
+ res = PQnfn(conn, conn->lobjfuncs->fn_lo_tell64,
+ (void *) &retval, sizeof(retval), &result_len, 0, argv, 1);
if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
{
PQclear(res);
diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index 0e36974..b4f0c10 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -1434,7 +1434,7 @@ pqEndcopy2(PGconn *conn)
*/
PGresult *
pqFunctionCall2(PGconn *conn, Oid fnid,
- int *result_buf, int *actual_result_len,
+ int *result_buf, int buf_size, int *actual_result_len,
int result_is_int,
const PQArgBlock *args, int nargs)
{
@@ -1516,6 +1516,20 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
}
else
{
+ /*
+ * If the server returned too much data for the
+ * buffer, something fishy is going on. Abandon ship.
+ */
+ if (buf_size != -1 && *actual_result_len > buf_size)
+ {
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("server returned too much data\n"));
+ conn->asyncStatus = PGASYNC_READY;
+ pqDropConnection(conn, true);
+ conn->status = CONNECTION_BAD;
+ return pqPrepareAsyncResult(conn);
+ }
+
if (pqGetnchar((char *) result_buf,
*actual_result_len,
conn))
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index c9f88ba..2931453 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -1893,7 +1893,7 @@ pqEndcopy3(PGconn *conn)
*/
PGresult *
pqFunctionCall3(PGconn *conn, Oid fnid,
- int *result_buf, int *actual_result_len,
+ int *result_buf, int buf_size, int *actual_result_len,
int result_is_int,
const PQArgBlock *args, int nargs)
{
@@ -2024,6 +2024,18 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
}
else
{
+ /*
+ * If the server returned too much data for the
+ * buffer, something fishy is going on. Abandon ship.
+ */
+ if (buf_size != -1 && *actual_result_len > buf_size)
+ {
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("server returned too much data\n"));
+ handleSyncLoss(conn, id, *actual_result_len);
+ return pqPrepareAsyncResult(conn);
+ }
+
if (pqGetnchar((char *) result_buf,
*actual_result_len,
conn))
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 7ecbd55..1a073ff 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -606,6 +606,9 @@ extern void pqSaveMessageField(PGresult *res, char code,
extern void pqSaveParameterStatus(PGconn *conn, const char *name,
const char *value);
extern int pqRowProcessor(PGconn *conn, const char **errmsgp);
+extern PGresult *PQnfn(PGconn *conn, int fnid, int *result_buf, int buf_size,
+ int *result_len, int result_is_int,
+ const PQArgBlock *args, int nargs);
/* === in fe-protocol2.c === */
@@ -619,7 +622,8 @@ extern int pqGetline2(PGconn *conn, char *s, int maxlen);
extern int pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize);
extern int pqEndcopy2(PGconn *conn);
extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid,
- int *result_buf, int *actual_result_len,
+ int *result_buf, int buf_size,
+ int *actual_result_len,
int result_is_int,
const PQArgBlock *args, int nargs);
@@ -636,7 +640,8 @@ extern int pqGetline3(PGconn *conn, char *s, int maxlen);
extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize);
extern int pqEndcopy3(PGconn *conn);
extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
- int *result_buf, int *actual_result_len,
+ int *result_buf, int buf_size,
+ int *actual_result_len,
int result_is_int,
const PQArgBlock *args, int nargs);
--
2.54.0

View File

@ -0,0 +1,250 @@
Created by combining upstream commit 4608619a1cf578f16e799510eaa0a21c0f1f08e3
that fixes the CVE
with upstream commit b282280e9b69cae988c0c69cce3eda4d4bd38fff
that provides the function the fix uses, `timingsafe_bcmp`
diff --git a/configure b/configure
index 350d426..7537c19 100755
--- a/configure
+++ b/configure
@@ -16305,6 +16305,16 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_RTLD_NOW $ac_have_decl
_ACEOF
+ac_fn_c_check_decl "$LINENO" "timingsafe_bcmp" "ac_cv_have_decl_timingsafe_bcmp" "$ac_includes_default"
+if test "x$ac_cv_have_decl_timingsafe_bcmp" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_TIMINGSAFE_BCMP $ac_have_decl
+_ACEOF
ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "$ac_includes_default
@@ -16617,6 +16627,19 @@ esac
fi
+ac_fn_c_check_func "$LINENO" "timingsafe_bcmp" "ac_cv_func_timingsafe_bcmp"
+if test "x$ac_cv_func_timingsafe_bcmp" = xyes; then :
+ $as_echo "#define HAVE_TIMINGSAFE_BCMP 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" timingsafe_bcmp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS timingsafe_bcmp.$ac_objext"
+ ;;
+esac
+
+fi
+
case $host_os in
diff --git a/configure.in b/configure.in
index ffce35e..a29366d 100644
--- a/configure.in
+++ b/configure.in
@@ -1780,7 +1780,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include <fcntl.h>])
]) # fi
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
-AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
+AC_CHECK_DECLS([strlcat, strlcpy, strnlen, timingsafe_bcmp])
# This is probably only present on macOS, but may as well check always
AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
@@ -1841,6 +1841,7 @@ AC_REPLACE_FUNCS(m4_normalize([
strlcpy
strnlen
strtof
+ timingsafe_bcmp
]))
case $host_os in
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c
index 6b60abe..def1fce 100644
--- a/src/backend/libpq/auth-scram.c
+++ b/src/backend/libpq/auth-scram.c
@@ -535,7 +535,7 @@ scram_verify_plain_password(const char *username, const char *password,
* Compare the verifier's Server Key with the one computed from the
* user-supplied password.
*/
- return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
+ return timingsafe_bcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
}
@@ -1050,9 +1050,9 @@ verify_final_nonce(scram_state *state)
if (final_nonce_len != client_nonce_len + server_nonce_len)
return false;
- if (memcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0)
+ if (timingsafe_bcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0)
return false;
- if (memcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0)
+ if (timingsafe_bcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0)
return false;
return true;
@@ -1093,7 +1093,7 @@ verify_client_proof(scram_state *state)
/* Hash it one more time, and compare with StoredKey */
scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey);
- if (memcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0)
+ if (timingsafe_bcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0)
return false;
return true;
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 98b4225..c61615f 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3345,7 +3345,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
}
pfree(cryptvector);
- if (memcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0)
+ if (timingsafe_bcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0)
{
ereport(LOG,
(errmsg("RADIUS response from %s has incorrect MD5 signature",
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c
index 6e273dc..95cd78d 100644
--- a/src/backend/libpq/crypt.c
+++ b/src/backend/libpq/crypt.c
@@ -199,7 +199,8 @@ md5_crypt_verify(const char *role, const char *shadow_pass,
return STATUS_ERROR;
}
- if (strcmp(client_pass, crypt_pwd) == 0)
+ if (strlen(client_pass) == strlen(crypt_pwd) &&
+ timingsafe_bcmp(client_pass, crypt_pwd, strlen(crypt_pwd)) == 0)
retval = STATUS_OK;
else
{
@@ -264,7 +265,8 @@ plain_crypt_verify(const char *role, const char *shadow_pass,
*/
return STATUS_ERROR;
}
- if (strcmp(crypt_client_pass, shadow_pass) == 0)
+ if (strlen(crypt_client_pass) == strlen(shadow_pass) &&
+ timingsafe_bcmp(crypt_client_pass, shadow_pass, strlen(shadow_pass)) == 0)
return STATUS_OK;
else
{
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c876033..d2f3477 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -189,6 +189,10 @@
don't. */
#undef HAVE_DECL_STRTOULL
+/* Define to 1 if you have the declaration of `timingsafe_bcmp', and to 0 if
+ you don't. */
+#undef HAVE_DECL_TIMINGSAFE_BCMP
+
/* Define to 1 if you have the `dlopen' function. */
#undef HAVE_DLOPEN
@@ -661,6 +665,9 @@
`HAVE_STRUCT_TM_TM_ZONE' instead. */
#undef HAVE_TM_ZONE
+/* Define to 1 if you have the `timingsafe_bcmp' function. */
+#undef HAVE_TIMINGSAFE_BCMP
+
/* Define to 1 if your compiler understands `typeof' or something similar. */
#undef HAVE_TYPEOF
diff --git a/src/include/port.h b/src/include/port.h
index 2229ec7..32925ad 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -497,6 +497,10 @@ extern int pqGethostbyname(const char *name,
struct hostent **result,
int *herrno);
+#if !HAVE_DECL_TIMINGSAFE_BCMP
+extern int timingsafe_bcmp(const void *b1, const void *b2, size_t len);
+#endif
+
extern void pg_qsort(void *base, size_t nel, size_t elsize,
int (*cmp) (const void *, const void *));
extern int pg_qsort_strcmp(const void *a, const void *b);
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index 6b55bff..f87e6f7 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -549,7 +549,7 @@ read_server_first_message(fe_scram_state *state, char *input)
/* Verify immediately that the server used our part of the nonce */
if (strlen(nonce) < strlen(state->client_nonce) ||
- memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0)
+ timingsafe_bcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("invalid SCRAM response (nonce mismatch)\n"));
@@ -748,7 +748,8 @@ verify_server_signature(fe_scram_state *state)
strlen(state->client_final_message_without_proof));
scram_HMAC_final(expected_ServerSignature, &ctx);
- if (memcmp(expected_ServerSignature, state->ServerSignature, SCRAM_KEY_LEN) != 0)
+ if (timingsafe_bcmp(expected_ServerSignature, state->ServerSignature,
+ SCRAM_KEY_LEN) != 0)
return false;
return true;
diff --git a/src/port/timingsafe_bcmp.c b/src/port/timingsafe_bcmp.c
new file mode 100644
index 0000000..fbad8a7
--- /dev/null
+++ b/src/port/timingsafe_bcmp.c
@@ -0,0 +1,43 @@
+/*
+ * src/port/timingsafe_bcmp.c
+ *
+ * $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $
+ */
+
+/*
+ * Copyright (c) 2010 Damien Miller. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "c.h"
+
+#ifdef USE_SSL
+#include <openssl/crypto.h>
+#endif
+
+int
+timingsafe_bcmp(const void *b1, const void *b2, size_t n)
+{
+#ifdef USE_SSL
+ return CRYPTO_memcmp(b1, b2, n);
+#else
+ const unsigned char *p1 = b1,
+ *p2 = b2;
+ int ret = 0;
+
+ for (; n > 0; n--)
+ ret |= *p1++ ^ *p2++;
+ return (ret != 0);
+#endif
+}

View File

@ -0,0 +1,202 @@
From 44abf5b7e2b9892edce3ec78bf26e1b5ebf796f9 Mon Sep 17 00:00:00 2001
From: Petr Khartskhaev <pkhartsk@redhat.com>
Date: Thu, 4 Jun 2026 16:01:19 +0200
Subject: [PATCH] refint: Fix SQL injection and buffer overruns.
Maliciously crafted key value updates could achieve SQL injection
within check_foreign_key(). To fix, ensure new key values are
properly quoted and escaped in the internally generated SQL
statements. While at it, avoid potential buffer overruns by
replacing the stack buffers for internally generated SQL statements
with StringInfo.
Reported-by: Nikolay Samokhvalov <nik@postgres.ai>
Author: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Security: CVE-2026-6637
Backpatch-through: 14
---
contrib/spi/refint.c | 84 ++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 46 deletions(-)
diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c
index adf0490..266f65e 100644
--- a/contrib/spi/refint.c
+++ b/contrib/spi/refint.c
@@ -165,21 +165,24 @@ check_primary_key(PG_FUNCTION_ARGS)
if (plan->nplans <= 0)
{
SPIPlanPtr pplan;
- char sql[8192];
+ StringInfoData sql;
+
+ initStringInfo(&sql);
/*
* Construct query: SELECT 1 FROM _referenced_relation_ WHERE Pkey1 =
* $1 [AND Pkey2 = $2 [...]]
*/
- snprintf(sql, sizeof(sql), "select 1 from %s where ", relname);
- for (i = 0; i < nkeys; i++)
+ appendStringInfo(&sql, "select 1 from %s where ", relname);
+ for (i = 1; i <= nkeys; i++)
{
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s = $%d %s",
- args[i + nkeys + 1], i + 1, (i < nkeys - 1) ? "and " : "");
+ appendStringInfo(&sql, "%s = $%d ", args[i + nkeys], i);
+ if (i < nkeys)
+ appendStringInfoString(&sql, "and ");
}
/* Prepare plan for query */
- pplan = SPI_prepare(sql, nkeys, argtypes);
+ pplan = SPI_prepare(sql.data, nkeys, argtypes);
if (pplan == NULL)
/* internal error */
elog(ERROR, "check_primary_key: SPI_prepare returned %s", SPI_result_code_string(SPI_result));
@@ -194,6 +197,8 @@ check_primary_key(PG_FUNCTION_ARGS)
plan->splan = (SPIPlanPtr *) malloc(sizeof(SPIPlanPtr));
*(plan->splan) = pplan;
plan->nplans = 1;
+
+ pfree(sql.data);
}
/*
@@ -414,13 +419,16 @@ check_foreign_key(PG_FUNCTION_ARGS)
if (plan->nplans <= 0)
{
SPIPlanPtr pplan;
- char sql[8192];
char **args2 = args;
plan->splan = (SPIPlanPtr *) malloc(nrefs * sizeof(SPIPlanPtr));
for (r = 0; r < nrefs; r++)
{
+ StringInfoData sql;
+
+ initStringInfo(&sql);
+
relname = args2[0];
/*---------
@@ -434,8 +442,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
*---------
*/
if (action == 'r')
-
- snprintf(sql, sizeof(sql), "select 1 from %s where ", relname);
+ appendStringInfo(&sql, "select 1 from %s where ", relname);
/*---------
* For 'C'ascade action we construct DELETE query
@@ -462,43 +469,24 @@ check_foreign_key(PG_FUNCTION_ARGS)
char *nv;
int k;
- snprintf(sql, sizeof(sql), "update %s set ", relname);
+ appendStringInfo(&sql, "update %s set ", relname);
for (k = 1; k <= nkeys; k++)
{
- int is_char_type = 0;
- char *type;
-
fn = SPI_fnumber(tupdesc, args_temp[k - 1]);
Assert(fn > 0); /* already checked above */
nv = SPI_getvalue(newtuple, tupdesc, fn);
- type = SPI_gettype(tupdesc, fn);
-
- if (strcmp(type, "text") == 0 ||
- strcmp(type, "varchar") == 0 ||
- strcmp(type, "char") == 0 ||
- strcmp(type, "bpchar") == 0 ||
- strcmp(type, "date") == 0 ||
- strcmp(type, "timestamp") == 0)
- is_char_type = 1;
-#ifdef DEBUG_QUERY
- elog(DEBUG4, "check_foreign_key Debug value %s type %s %d",
- nv, type, is_char_type);
-#endif
- /*
- * is_char_type =1 i set ' ' for define a new value
- */
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
- " %s = %s%s%s %s ",
- args2[k], (is_char_type > 0) ? "'" : "",
- nv, (is_char_type > 0) ? "'" : "", (k < nkeys) ? ", " : "");
+ appendStringInfo(&sql, " %s = %s ",
+ args2[k], quote_literal_cstr(nv));
+ if (k < nkeys)
+ appendStringInfoString(&sql, ", ");
}
- strcat(sql, " where ");
+ appendStringInfoString(&sql, " where ");
}
else
/* DELETE */
- snprintf(sql, sizeof(sql), "delete from %s where ", relname);
+ appendStringInfo(&sql, "delete from %s where ", relname);
}
@@ -510,25 +498,26 @@ check_foreign_key(PG_FUNCTION_ARGS)
*/
else if (action == 's')
{
- snprintf(sql, sizeof(sql), "update %s set ", relname);
+ appendStringInfo(&sql, "update %s set ", relname);
for (i = 1; i <= nkeys; i++)
{
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
- "%s = null%s",
- args2[i], (i < nkeys) ? ", " : "");
+ appendStringInfo(&sql, "%s = null", args2[i]);
+ if (i < nkeys)
+ appendStringInfoString(&sql, ", ");
}
- strcat(sql, " where ");
+ appendStringInfoString(&sql, " where ");
}
/* Construct WHERE qual */
for (i = 1; i <= nkeys; i++)
{
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s = $%d %s",
- args2[i], i, (i < nkeys) ? "and " : "");
+ appendStringInfo(&sql, "%s = $%d ", args2[i], i);
+ if (i < nkeys)
+ appendStringInfoString(&sql, "and ");
}
/* Prepare plan for query */
- pplan = SPI_prepare(sql, nkeys, argtypes);
+ pplan = SPI_prepare(sql.data, nkeys, argtypes);
if (pplan == NULL)
/* internal error */
elog(ERROR, "check_foreign_key: SPI_prepare returned %s", SPI_result_code_string(SPI_result));
@@ -544,11 +533,14 @@ check_foreign_key(PG_FUNCTION_ARGS)
plan->splan[r] = pplan;
args2 += nkeys + 1; /* to the next relation */
+
+#ifdef DEBUG_QUERY
+ elog(DEBUG4, "check_foreign_key Debug Query is : %s ", sql.data);
+#endif
+
+ pfree(sql.data);
}
plan->nplans = nrefs;
-#ifdef DEBUG_QUERY
- elog(DEBUG4, "check_foreign_key Debug Query is : %s ", sql);
-#endif
}
/*
--
2.54.0

View File

@ -0,0 +1,43 @@
We don't build/install interfaces by upstream's implicit rules.
This patch is used on two places; postgresql.spec and libecpg.spec -- keep those
in sync!
Related: rhbz#1618698
diff --git a/src/Makefile b/src/Makefile
index bcdbd95..4bea236 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,7 +20,6 @@ SUBDIRS = \
backend/utils/mb/conversion_procs \
backend/snowball \
include \
- interfaces \
backend/replication/libpqwalreceiver \
backend/replication/pgoutput \
fe_utils \
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index b9d86ac..29df69f 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -549,7 +549,7 @@ endif
# How to link to libpq. (This macro may be used as-is by backend extensions.
# Client-side code should go through libpq_pgport or libpq_pgport_shlib,
# instead.)
-libpq = -L$(libpq_builddir) -lpq
+libpq = -lpq
# libpq_pgport is for use by client executables (not libraries) that use libpq.
# We want clients to pull symbols from the non-shared libraries libpgport
@@ -579,7 +579,6 @@ endif
# Commonly used submake targets
submake-libpq: | submake-generated-headers
- $(MAKE) -C $(libpq_builddir) all
submake-libpgport: | submake-generated-headers
$(MAKE) -C $(top_builddir)/src/port all
--
2.21.0

View File

@ -1,33 +0,0 @@
diff --git a/src/Makefile b/src/Makefile
index febbced..9737b55 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,7 +20,6 @@ SUBDIRS = \
backend/utils/mb/conversion_procs \
backend/snowball \
include \
- interfaces \
backend/replication/libpqwalreceiver \
backend/replication/pgoutput \
fe_utils \
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4ed5174..d0e0dae 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -457,7 +457,7 @@ endif
# This macro is for use by libraries linking to libpq. (Because libpgport
# isn't created with the same link flags as libpq, it can't be used.)
-libpq = -L$(libpq_builddir) -lpq
+libpq = -lpq
# This macro is for use by client executables (not libraries) that use libpq.
# We force clients to pull symbols from the non-shared libraries libpgport
@@ -483,7 +483,6 @@ endif
# Commonly used submake targets
submake-libpq:
- $(MAKE) -C $(libpq_builddir) all
submake-libpgport:
$(MAKE) -C $(top_builddir)/src/port all

View File

@ -1,5 +1,13 @@
We should ideally provide '/bin/pg_config' in postgresql-server-devel, and
provide no pg_config binary in libpq package. But most of the Fedora packages
that use pg_config actually only build against PG libraries (and
postgresql-server-devel isn't needed). So.., to avoid the initial rush around
rhbz#1618698 change, rather provide pg_server_config binary, which int urn means
that we'll have to fix only a minimal set of packages which really build
PostgreSQL server modules.
diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile
index c410087..e546b7b 100644
index 02e6f9d..f7c844f 100644
--- a/src/bin/pg_config/Makefile
+++ b/src/bin/pg_config/Makefile
@@ -11,28 +11,30 @@
@ -40,12 +48,12 @@ index c410087..e546b7b 100644
check:
diff --git a/src/bin/pg_config/nls.mk b/src/bin/pg_config/nls.mk
index 1d41f90ee0..0f34f371cc 100644
index 1d41f90..0f34f37 100644
--- a/src/bin/pg_config/nls.mk
+++ b/src/bin/pg_config/nls.mk
@@ -1,4 +1,4 @@
# src/bin/pg_config/nls.mk
-CATALOG_NAME = pg_config
+CATALOG_NAME = pg_server_config
AVAIL_LANGUAGES = cs de es fr he it ja ko nb pl pt_BR ro ru sv ta tr zh_CN zh_TW
AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ro ru sv tr uk vi zh_CN zh_TW
GETTEXT_FILES = pg_config.c ../../common/config_info.c ../../common/exec.c

View File

@ -0,0 +1,84 @@
From dee1e86d0e6d20c6326073db1736ae2088aac191 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 20 Jan 2025 15:47:53 -0500
Subject: [PATCH] Avoid using timezone Asia/Manila in regression tests.
The freshly-released 2025a version of tzdata has a refined estimate
for the longitude of Manila, changing their value for LMT in
pre-standardized-timezone days. This changes the output of one of
our test cases. Since we need to be able to run with system tzdata
files that may or may not contain this update, we'd better stop
making that specific test.
I switched it to use Asia/Singapore, which has a roughly similar UTC
offset. That LMT value hasn't changed in tzdb since 2003, so we can
hope that it's well established.
I also noticed that this set of make_timestamptz tests only exercises
zones east of Greenwich, which seems rather sad, and was not the
original intent AFAICS. (We've already changed these tests once
to stabilize their results across tzdata updates, cf 66b737cd9;
it looks like I failed to consider the UTC-offset-sign aspect then.)
To improve that, add a test with Pacific/Honolulu. That LMT offset
is also quite old in tzdb, so we'll cross our fingers that it doesn't
get improved.
Reported-by: Christoph Berg <cb@df7cb.de>
Discussion: https://postgr.es/m/Z46inkznCxesvDEb@msg.df7cb.de
Backpatch-through: 13
---
src/include/datatype/timestamp.h | 2 +-
src/test/regress/expected/timestamptz.out | 10 ++++++++--
src/test/regress/sql/timestamptz.sql | 3 ++-
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h
index 6be6d35d1e2c2..92b1cca9901be 100644
--- a/src/include/datatype/timestamp.h
+++ b/src/include/datatype/timestamp.h
@@ -96,7 +96,7 @@ typedef struct
/*
* We allow numeric timezone offsets up to 15:59:59 either way from Greenwich.
* Currently, the record holders for wackiest offsets in actual use are zones
- * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42
+ * Asia/Manila, at -15:56:08 until 1844, and America/Metlakatla, at +15:13:42
* until 1867. If we were to reject such values we would fail to dump and
* restore old timestamptz values with these zone settings.
*/
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index 0ce33862019b2..77abfab1f6663 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -2072,10 +2072,16 @@ SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UT
Tue Dec 09 23:00:00 2014
(1 row)
-SELECT make_timestamptz(1846, 12, 10, 0, 0, 0, 'Asia/Manila') AT TIME ZONE 'UTC';
+SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC';
timezone
--------------------------
- Wed Dec 09 15:56:00 1846
+ Fri Dec 09 17:04:35 1881
+(1 row)
+
+SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC';
+ timezone
+--------------------------
+ Sat Dec 10 10:31:26 1881
(1 row)
SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC';
diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql
index f0a8d3e5aa6dc..ac0bc14854956 100644
--- a/src/test/regress/sql/timestamptz.sql
+++ b/src/test/regress/sql/timestamptz.sql
@@ -331,7 +331,8 @@ SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') = '1973-07-15 08:15:5
-- full timezone names
SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') = timestamptz '2014-12-10 00:00:00 Europe/Prague';
SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UTC';
-SELECT make_timestamptz(1846, 12, 10, 0, 0, 0, 'Asia/Manila') AT TIME ZONE 'UTC';
+SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC';
+SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC';
SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC';
SELECT make_timestamptz(1910, 12, 24, 0, 0, 0, 'Nehwon/Lankhmar');

View File

@ -38,6 +38,7 @@
%{!?pltcl:%global pltcl 1}
%{!?plperl:%global plperl 1}
%{!?ssl:%global ssl 1}
%{!?icu:%global icu 1}
%{!?kerberos:%global kerberos 1}
%{!?ldap:%global ldap 1}
%{!?nls:%global nls 1}
@ -57,33 +58,32 @@
Summary: PostgreSQL client programs
Name: postgresql
%global majorversion 10
Version: %{majorversion}.23
Release: 3%{?dist}
%global majorversion 12
Version: %{majorversion}.22
Release: 7%{?dist}
# The PostgreSQL license is very similar to other MIT licenses, but the OSI
# recognizes it as an independent license, so we do as well.
License: PostgreSQL
Group: Applications/Databases
Url: http://www.postgresql.org/
# This SRPM includes a copy of the previous major release, which is needed for
# in-place upgrade of an old database. In most cases it will not be critical
# that this be kept up with the latest minor release of the previous series;
# but update when bugs affecting pg_dump output are fixed.
%global prevversion 9.2.24
%global prevmajorversion 9.2
%global prevmajorversion 10
%global prevversion %{prevmajorversion}.23
%global prev_prefix %{_libdir}/pgsql/postgresql-%{prevmajorversion}
%global precise_version %{?epoch:%epoch:}%version-%release
%global setup_version 8.7
%global service_name postgresql.service
Source0: https://ftp.postgresql.org/pub/source/v%{version}/postgresql-%{version}.tar.bz2
# The PDF file is generated by generate-pdf.sh, which see for comments
# PDF can be downloaded from the upstream
# Don't forget to rename the PDF file with the full version prefix (e.g. postgresql-12.22-US.pdf)
Source1: postgresql-%{version}-US.pdf
# generate-pdf.sh is not used during RPM build, but include for documentation
Source2: generate-pdf.sh
Source3: https://ftp.postgresql.org/pub/source/v%{prevversion}/postgresql-%{prevversion}.tar.bz2
Source4: Makefile.regress
Source9: postgresql.tmpfiles.d
@ -105,16 +105,24 @@ Patch1: rpm-pgsql.patch
Patch2: postgresql-logging.patch
Patch5: postgresql-var-run-socket.patch
Patch6: postgresql-man.patch
Patch8: postgresql-no-libs.patch
Patch8: postgresql-external-libpq.patch
Patch9: postgresql-server-pg_config.patch
Patch10: postgresql-10.15-contrib-dblink-expected-out.patch
Patch11: postgresql-10.23-CVE-2023-2454.patch
Patch12: postgresql-10.23-CVE-2023-2455.patch
Patch13: postgresql-10.23-CVE-2023-5869.patch
Patch10: postgresql-12.5-contrib-dblink-expected-out.patch
Patch11: backport-cve-2025-1094.patch
Patch12: timezone-test-fix.patch
Patch13: CVE-2025-8715.patch
Patch14: CVE-2026-2004--CVE-2026-2005--CVE-2026-2006.patch
Patch15: postgresql-CVE-2026-6478.patch
Patch16: postgresql-CVE-2026-6637.patch
Patch17: postgresql-CVE-2026-6477.patch
Patch18: postgresql-CVE-2026-6475.patch
Patch19: postgresql-CVE-2026-6473.patch
BuildRequires: gcc
BuildRequires: perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk
BuildRequires: perl(ExtUtils::Embed), perl-devel
BuildRequires: perl(Opcode)
BuildRequires: perl(FindBin)
%if 0%{?fedora} || 0%{?rhel} > 7
BuildRequires: perl-generators
%endif
@ -122,6 +130,8 @@ BuildRequires: readline-devel zlib-devel
BuildRequires: systemd systemd-devel util-linux
BuildRequires: multilib-rpm-config
BuildRequires: libpq-devel
BuildRequires: docbook-style-xsl
# postgresql-setup build requires
BuildRequires: m4 elinks docbook-utils help2man
@ -174,6 +184,10 @@ BuildRequires: systemtap-sdt-devel
BuildRequires: libselinux-devel
%endif
%if %icu
BuildRequires: libicu-devel
%endif
# https://bugzilla.redhat.com/1464368
%global __provides_exclude_from %{_libdir}/pgsql
@ -189,7 +203,6 @@ postgresql-server sub-package.
%package server
Summary: The programs needed to create and run a PostgreSQL server
Group: Applications/Databases
Requires: %{name}%{?_isa} = %precise_version
Requires(pre): /usr/sbin/useradd
# We require this to be present for %%{_prefix}/lib/tmpfiles.d
@ -213,7 +226,6 @@ and maintain PostgreSQL databases.
%package docs
Summary: Extra documentation for PostgreSQL
Group: Applications/Databases
Requires: %{name}%{?_isa} = %precise_version
# Just for more intuitive documentation installation
Provides: %{name}-doc = %precise_version
@ -226,7 +238,6 @@ and source files for the PostgreSQL tutorial.
%package contrib
Summary: Extension modules distributed with PostgreSQL
Group: Applications/Databases
Requires: %{name}%{?_isa} = %precise_version
%description contrib
@ -236,19 +247,21 @@ included in the PostgreSQL distribution.
%package server-devel
Summary: PostgreSQL development header files and libraries
Group: Development/Libraries
%if %icu
Requires: libicu-devel
%endif
%if %kerberos
Requires: krb5-devel
%endif
%description server-devel
The postgresql-server-devel package contains the header files and libraries
needed to compile C or C++ applications which will directly interact
with a PostgreSQL database management server. It also contains the ecpg
Embedded C Postgres preprocessor. You need to install this package if you want
to develop applications which will interact with a PostgreSQL server.
The postgresql-server-devel package contains the header files and configuration
needed to compile PostgreSQL server extension.
%package test-rpm-macros
Summary: Convenience RPM macros for build-time testing against PostgreSQL server
Requires: %{name}-server = %precise_version
BuildArch: noarch
%description test-rpm-macros
This package is meant to be added as BuildRequires: dependency of other packages
@ -267,9 +280,8 @@ counterparts.
%if %upgrade
%package upgrade
Summary: Support for upgrading from the previous major release of PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
Provides: bundled(postgresql-libs) = %prevversion
Provides: bundled(postgresql-server) = %prevversion
%description upgrade
The postgresql-upgrade package contains the pg_upgrade utility and supporting
@ -279,7 +291,6 @@ version of PostgreSQL.
%package upgrade-devel
Summary: Support for build of extensions required for upgrade process
Group: Development/Libraries
Requires: %{name}-upgrade%{?_isa} = %precise_version
%description upgrade-devel
@ -292,7 +303,6 @@ process.
%if %plperl
%package plperl
Summary: The Perl procedural language for PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
%if %runselftest
@ -309,7 +319,6 @@ Install this if you want to write database functions in Perl.
%if %plpython
%package plpython
Summary: The Python2 procedural language for PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
Provides: %{name}-plpython2 = %precise_version
@ -323,7 +332,6 @@ Install this if you want to write database functions in Python 2.
%if %plpython3
%package plpython3
Summary: The Python3 procedural language for PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
%description plpython3
@ -336,7 +344,6 @@ Install this if you want to write database functions in Python 3.
%if %pltcl
%package pltcl
Summary: The Tcl procedural language for PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
%description pltcl
@ -349,7 +356,6 @@ Install this if you want to write database functions in Tcl.
%if %test
%package test
Summary: The test suite distributed with PostgreSQL
Group: Applications/Databases
Requires: %{name}-server%{?_isa} = %precise_version
Requires: %{name}-server-devel%{?_isa} = %precise_version
@ -361,8 +367,14 @@ benchmarks.
%prep
( cd %_sourcedir; sha256sum -c %{SOURCE16}; sha256sum -c %{SOURCE17} )
%setup -q -a 12
(
cd "$(dirname "%{SOURCE0}")"
sha256sum -c %{SOURCE16}
%if %upgrade
sha256sum -c %{SOURCE17}
%endif
)
%setup -q -a 12 -n postgresql-%{version}
%patch1 -p1
%patch2 -p1
%patch5 -p1
@ -373,6 +385,12 @@ benchmarks.
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
# We used to run autoconf here, but there's no longer any real need to,
# since Postgres ships with a reasonably modern configure script.
@ -473,6 +491,9 @@ common_configure_options='
--with-system-tzdata=%_datadir/zoneinfo
--datadir=%_datadir/pgsql
--with-systemd
%if %icu
--with-icu
%endif
'
%if %plpython3
@ -484,9 +505,21 @@ export PYTHON=/usr/bin/python3
--with-python
# Fortunately we don't need to build much except plpython itself.
make %{?_smp_mflags} -C src/pl/plpython all
%global python_subdirs \\\
src/pl/plpython \\\
contrib/hstore_plpython \\\
contrib/jsonb_plpython \\\
contrib/ltree_plpython
for dir in %python_subdirs; do
%make_build -C "$dir" all
done
# save built form in a directory that "make distclean" won't touch
cp -a src/pl/plpython src/pl/plpython3
for dir in %python_subdirs; do
rm -rf "${dir}3" # shouldn't exist, unless --short-circuit
cp -a "$dir" "${dir}3"
done
# must also save this version of Makefile.global for later
cp src/Makefile.global src/Makefile.global.python3
@ -505,7 +538,7 @@ PYTHON=/usr/bin/python2
unset PYTHON
make %{?_smp_mflags} world
%make_build world
# Have to hack makefile to put correct path into tutorial scripts
sed "s|C=\`pwd\`;|C=%{_libdir}/pgsql/tutorial;|" < src/tutorial/Makefile > src/tutorial/GNUmakefile
@ -545,17 +578,25 @@ test_failure=0
mv src/Makefile.global src/Makefile.global.save
cp src/Makefile.global.python3 src/Makefile.global
touch -r src/Makefile.global.save src/Makefile.global
# because "make check" does "make install" on the whole tree,
# we must temporarily install plpython3 as src/pl/plpython,
# since that is the subdirectory src/pl/Makefile knows about
mv src/pl/plpython src/pl/plpython2
mv src/pl/plpython3 src/pl/plpython
run_testsuite "src/pl/plpython"
for dir in %python_subdirs; do
# because "make check" does "make install" on the whole tree,
# we must temporarily install *plpython3 dir as *plpython,
# since that is the subdirectory src/pl/Makefile knows about
mv "$dir" "${dir}2"
mv "${dir}3" "$dir"
done
for dir in %python_subdirs; do
run_testsuite "$dir"
done
for dir in %python_subdirs; do
# and clean up our mess
mv "$dir" "${dir}3"
mv "${dir}2" "${dir}"
done
# and clean up our mess
mv src/pl/plpython src/pl/plpython3
mv src/pl/plpython2 src/pl/plpython
mv -f src/Makefile.global.save src/Makefile.global
%endif
run_testsuite "contrib"
@ -598,6 +639,9 @@ upgrade_configure ()
--enable-debug \
--enable-cassert \
%endif
%if %icu
--with-icu \
%endif
%if %plperl
--with-perl \
%endif
@ -615,11 +659,14 @@ upgrade_configure ()
%if %plpython3
export PYTHON=/usr/bin/python3
upgrade_configure --with-python
# upstream fixed this later 7107d58ec5a3c45967e77525809612a5f89b97f3
make %{?_smp_mflags} -C src/backend submake-errcodes
make %{?_smp_mflags} -C src/pl/plpython all
# save aside the only one file which we are interested here
cp src/pl/plpython/plpython3.so ./
for dir in %python_subdirs; do
# Previous version doesn't necessarily have this.
test -d "$dir" || continue
%make_build -C "$dir" all
# save aside the only one file which we are interested here
cp "$dir"/*plpython3.so ./
done
unset PYTHON
make distclean
%endif
@ -667,9 +714,9 @@ rm -r $RPM_BUILD_ROOT/%_includedir/pgsql/internal/
mv src/Makefile.global src/Makefile.global.save
cp src/Makefile.global.python3 src/Makefile.global
touch -r src/Makefile.global.save src/Makefile.global
pushd src/pl/plpython3
make DESTDIR=$RPM_BUILD_ROOT install
popd
for dir in %python_subdirs; do
%make_install -C "${dir}3"
done
mv -f src/Makefile.global.save src/Makefile.global
%endif
@ -716,8 +763,10 @@ rm $RPM_BUILD_ROOT/%{_datadir}/man/man1/ecpg.1
make DESTDIR=$RPM_BUILD_ROOT install
make -C contrib DESTDIR=$RPM_BUILD_ROOT install
%if %plpython3
install -m 755 plpython3.so \
$RPM_BUILD_ROOT/%_libdir/pgsql/postgresql-%prevmajorversion/lib
for file in *plpython3.so; do
install -m 755 "$file" \
$RPM_BUILD_ROOT/%_libdir/pgsql/postgresql-%prevmajorversion/lib
done
%endif
popd
@ -725,10 +774,8 @@ rm $RPM_BUILD_ROOT/%{_datadir}/man/man1/ecpg.1
pushd $RPM_BUILD_ROOT%{_libdir}/pgsql/postgresql-%{prevmajorversion}
rm bin/clusterdb
rm bin/createdb
rm bin/createlang
rm bin/createuser
rm bin/dropdb
rm bin/droplang
rm bin/dropuser
rm bin/ecpg
rm bin/initdb
@ -736,6 +783,7 @@ rm $RPM_BUILD_ROOT/%{_datadir}/man/man1/ecpg.1
rm bin/pg_dump
rm bin/pg_dumpall
rm bin/pg_restore
rm bin/pgbench
rm bin/psql
rm bin/reindexdb
rm bin/vacuumdb
@ -797,30 +845,23 @@ rm -f $RPM_BUILD_ROOT%{_bindir}/pgsql/hstore_plperl.so
rm -f $RPM_BUILD_ROOT%{_bindir}/pgsql/hstore_plpython2.so
%endif
# initialize file lists
cp /dev/null main.lst
cp /dev/null server.lst
cp /dev/null contrib.lst
cp /dev/null plperl.lst
cp /dev/null pltcl.lst
cp /dev/null plpython.lst
cp /dev/null plpython3.lst
%if %nls
find_lang_bins ()
{
lstfile=$1 ; shift
cp /dev/null "$lstfile"
for binary; do
%find_lang "$binary"-%{majorversion}
cat "$binary"-%{majorversion}.lang >>$lstfile
cat "$binary"-%{majorversion}.lang >>"$lstfile"
done
}
find_lang_bins devel.lst pg_server_config
find_lang_bins server.lst \
initdb pg_basebackup pg_controldata pg_ctl pg_resetwal pg_rewind plpgsql postgres
initdb pg_basebackup pg_controldata pg_ctl pg_resetwal pg_rewind plpgsql \
postgres pg_checksums
find_lang_bins contrib.lst \
pg_archivecleanup pg_test_fsync pg_test_timing pg_waldump
find_lang_bins main.lst \
find_lang_bins main.lst \
pg_dump pg_upgrade pgscripts psql
%if %plperl
find_lang_bins plperl.lst plperl
@ -859,14 +900,10 @@ find_lang_bins pltcl.lst pltcl
make -C postgresql-setup-%{setup_version} check
%endif
%clean
# FILES sections.
%files -f main.lst
%doc doc/KNOWN_BUGS doc/MISSING_FEATURES doc/TODO
%doc COPYRIGHT README HISTORY doc/bug.template
%doc COPYRIGHT README HISTORY
%doc README.rpm-dist
%{_bindir}/clusterdb
%{_bindir}/createdb
@ -913,13 +950,14 @@ make -C postgresql-setup-%{setup_version} check
%{_bindir}/pg_waldump
%{_bindir}/pgbench
%{_bindir}/vacuumlo
%dir %{_datadir}/pgsql/contrib
%dir %{_datadir}/pgsql/extension
%{_datadir}/pgsql/extension/adminpack*
%{_datadir}/pgsql/extension/amcheck*
%{_datadir}/pgsql/extension/autoinc*
%{_datadir}/pgsql/extension/bloom*
%{_datadir}/pgsql/extension/btree_gin*
%{_datadir}/pgsql/extension/btree_gist*
%{_datadir}/pgsql/extension/chkpass*
%{_datadir}/pgsql/extension/citext*
%{_datadir}/pgsql/extension/cube*
%{_datadir}/pgsql/extension/dblink*
@ -933,6 +971,18 @@ make -C postgresql-setup-%{setup_version} check
%{_datadir}/pgsql/extension/intagg*
%{_datadir}/pgsql/extension/intarray*
%{_datadir}/pgsql/extension/isn*
%if %{plperl}
%{_datadir}/pgsql/extension/jsonb_plperl*
%endif
%if %{plpython}
%{_datadir}/pgsql/extension/jsonb_plpythonu*
%{_datadir}/pgsql/extension/jsonb_plpython2u*
%endif
%if %{plpython3}
%{_datadir}/pgsql/extension/jsonb_plpythonu*
%{_datadir}/pgsql/extension/jsonb_plpython2u*
%{_datadir}/pgsql/extension/jsonb_plpython3u*
%endif
%{_datadir}/pgsql/extension/lo*
%{_datadir}/pgsql/extension/ltree*
%{_datadir}/pgsql/extension/moddatetime*
@ -951,7 +1001,6 @@ make -C postgresql-setup-%{setup_version} check
%{_datadir}/pgsql/extension/seg*
%{_datadir}/pgsql/extension/tablefunc*
%{_datadir}/pgsql/extension/tcn*
%{_datadir}/pgsql/extension/timetravel*
%{_datadir}/pgsql/extension/tsm_system_rows*
%{_datadir}/pgsql/extension/tsm_system_time*
%{_datadir}/pgsql/extension/unaccent*
@ -964,7 +1013,6 @@ make -C postgresql-setup-%{setup_version} check
%{_libdir}/pgsql/bloom.so
%{_libdir}/pgsql/btree_gin.so
%{_libdir}/pgsql/btree_gist.so
%{_libdir}/pgsql/chkpass.so
%{_libdir}/pgsql/citext.so
%{_libdir}/pgsql/cube.so
%{_libdir}/pgsql/dblink.so
@ -980,13 +1028,28 @@ make -C postgresql-setup-%{setup_version} check
%if %plpython
%{_libdir}/pgsql/hstore_plpython2.so
%endif
%if %plpython3
%{_libdir}/pgsql/hstore_plpython3.so
%endif
%{_libdir}/pgsql/insert_username.so
%{_libdir}/pgsql/isn.so
%if %plperl
%{_libdir}/pgsql/jsonb_plperl.so
%endif
%if %plpython
%{_libdir}/pgsql/jsonb_plpython2.so
%endif
%if %plpython3
%{_libdir}/pgsql/jsonb_plpython3.so
%endif
%{_libdir}/pgsql/lo.so
%{_libdir}/pgsql/ltree.so
%if %plpython
%{_libdir}/pgsql/ltree_plpython2.so
%endif
%if %plpython3
%{_libdir}/pgsql/ltree_plpython3.so
%endif
%{_libdir}/pgsql/moddatetime.so
%{_libdir}/pgsql/pageinspect.so
%{_libdir}/pgsql/passwordcheck.so
@ -1004,7 +1067,6 @@ make -C postgresql-setup-%{setup_version} check
%{_libdir}/pgsql/tablefunc.so
%{_libdir}/pgsql/tcn.so
%{_libdir}/pgsql/test_decoding.so
%{_libdir}/pgsql/timetravel.so
%{_libdir}/pgsql/tsm_system_rows.so
%{_libdir}/pgsql/tsm_system_time.so
%{_libdir}/pgsql/unaccent.so
@ -1044,6 +1106,7 @@ make -C postgresql-setup-%{setup_version} check
%{_bindir}/pg_recvlogical
%{_bindir}/pg_resetwal
%{_bindir}/pg_rewind
%{_bindir}/pg_checksums
%{_bindir}/postgres
%{_bindir}/postgresql-setup
%{_bindir}/postgresql-upgrade
@ -1051,7 +1114,6 @@ make -C postgresql-setup-%{setup_version} check
%dir %{_datadir}/pgsql
%{_datadir}/pgsql/*.sample
%dir %{_datadir}/pgsql/contrib
%{_datadir}/pgsql/conversion_create.sql
%dir %{_datadir}/pgsql/extension
%{_datadir}/pgsql/extension/plpgsql*
%{_datadir}/pgsql/information_schema.sql
@ -1065,6 +1127,7 @@ make -C postgresql-setup-%{setup_version} check
%{_datadir}/pgsql/tsearch_data/
%dir %{_datadir}/postgresql-setup
%{_datadir}/postgresql-setup/library.sh
%dir %{_libdir}/pgsql
%{_libdir}/pgsql/*_and_*.so
%{_libdir}/pgsql/dict_snowball.so
%{_libdir}/pgsql/euc2004_sjis2004.so
@ -1085,11 +1148,12 @@ make -C postgresql-setup-%{setup_version} check
%{_mandir}/man1/pg_receivewal.*
%{_mandir}/man1/pg_resetwal.*
%{_mandir}/man1/pg_rewind.*
%{_mandir}/man1/pg_checksums.*
%{_mandir}/man1/postgres.*
%{_mandir}/man1/postgresql-new-systemd-unit.*
%{_mandir}/man1/postgresql-setup.*
%{_mandir}/man1/postmaster.*
%{_mandir}/man1/postgresql-upgrade.*
%{_mandir}/man1/postmaster.*
%{_sbindir}/postgresql-new-systemd-unit
%{_tmpfilesdir}/postgresql.conf
%{_unitdir}/*postgresql*.service
@ -1105,9 +1169,10 @@ make -C postgresql-setup-%{setup_version} check
%files server-devel -f devel.lst
%{_bindir}/pg_server_config
%dir %{_datadir}/pgsql
%{_datadir}/pgsql/errcodes.txt
%dir %{_includedir}/pgsql
%dir %{_includedir}/pgsql/server
%{_includedir}/pgsql/server/*
%{_includedir}/pgsql/server
%{_libdir}/pgsql/pgxs/
%{_mandir}/man1/pg_server_config.*
%{_mandir}/man3/SPI_*
@ -1122,6 +1187,8 @@ make -C postgresql-setup-%{setup_version} check
%files static
%{_libdir}/libpgcommon.a
%{_libdir}/libpgport.a
%{_libdir}/libpgcommon_shlib.a
%{_libdir}/libpgport_shlib.a
%if %upgrade
@ -1130,12 +1197,14 @@ make -C postgresql-setup-%{setup_version} check
%exclude %{_libdir}/pgsql/postgresql-%{prevmajorversion}/bin/pg_config
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/lib
%exclude %{_libdir}/pgsql/postgresql-%{prevmajorversion}/lib/pgxs
%exclude %{_libdir}/pgsql/postgresql-%{prevmajorversion}/lib/pkgconfig
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/share
%files upgrade-devel
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/bin/pg_config
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/include
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/lib/pkgconfig
%{_libdir}/pgsql/postgresql-%{prevmajorversion}/lib/pgxs
%{macrosdir}/macros.%name-upgrade
%endif
@ -1177,114 +1246,259 @@ make -C postgresql-setup-%{setup_version} check
%changelog
* Mon Dec 18 2023 Lubos Kloucek <lubos.kloucek@oracle.com> - 10.23-3
- Resolves: CVE-2023-5869
* Thu Jun 4 2026 Petr Khartskhaev <pkhartsk@redhat.com> - 12.22-7
- Backport fix for CVE-2026-6478 from PostgreSQL 14.23
- Backport fixes for CVE-2026-6637, CVE-2026-6477, CVE-2026-6475, CVE-2026-6473
- Resolves: RHEL-179790
* Tue Aug 08 2023 David Sloboda <david.x.sloboda@oracle.com> - 10.23-2.0.1
- Fixed postgresql port binding issue during bootup [Orabug: 35103668]
* Fri Feb 27 2026 Filip Janus <fjanus@redhat.com> - 12.22-6
- Fix CVE-2026-2004 CVE-2026-2005 CVE-2026-2006
* Wed Jul 19 2023 Dominik Rehák <drehak@redhat.com> - 10.23-2
- Backport fixes for CVE-2023-2454 and CVE-2023-2455
* Mon Aug 18 2025 Filip Janus <fjanus@redhat.com> - 12.22-5
- Fix previous Backport
* Mon Aug 18 2025 Filip Janus <fjanus@redhat.com> - 12.22-4
- Backport CVE-2025-8715
* Tue Mar 18 2025 Filip Janus <fjanus@redhat.com> - 12.22-3
- Fix backport for CVE-2025-1094
* Tue Mar 18 2025 Filip Janus <fjanus@redhat.com> - 12.22-2
- Backport fix for CVE-2025-1094
* Thu Nov 21 2024 Lukas Javorsky <ljavorsk@redhat.com> - 12.22-1
- Update to 12.22
- Fixes: CVE-2024-10976 CVE-2024-10978
* Mon Aug 12 2024 Ales Nezbeda <anezbeda@redhat.com> - 12.20-1
- Update to 12.20
- Fix CVE-2024-7348
* Fri Feb 9 2024 Filip Janus <fjanus@redhat.com> - 12.18-1
- Update to 12.18
- Fix CVE-2024-0985
* Tue Nov 28 2023 Dominik Rehák <drehak@redhat.com> - 12.17-1
- Update to version 12.17
Fix: CVE-2023-5868, CVE-2023-5869, CVE-2023-5870
* Wed Jul 12 2023 Dominik Rehák <drehak@redhat.com> - 12.15-3
- Update postgresql-setup to 8.7 (https://github.com/devexp-db/postgresql-setup/pull/35)
- Resolves: #2207931
* Wed Nov 16 2022 Filip Januš <fjanus@redhat.com> - 10.23-1
- Resolves: CVE-2022-2625
- Rebase to 10.23
* Tue Jul 11 2023 Dominik Rehák <drehak@redhat.com> - 12.15-2
- Fix PostgreSQL 10 version used in specfile
* Mon May 16 2022 Filip Januš <fjanus@redhat.com> - 10.21-1
* Mon Jun 12 2023 Dominik Rehák <drehak@redhat.com> - 12.15-1
- Resolves: #2207932
- Update to version 12.15
* Fri Sep 30 2022 Filip Januš <fjanus@redhat.com> - 12.12-1
- Resolves: #2114732
- Update to version 12.12
* Mon May 16 2022 Filip Januš <fjanus@redhat.com> - 12.11-1
- Resolves: CVE-2022-1552
- Update to 10.21
- Release notes: https://www.postgresql.org/docs/release/10.21/
- Update to 12.11
- Release notes: https://www.postgresql.org/docs/release/12.11/
* Mon Dec 13 2021 Filip Januš <fjanus@redhat.com> - 10.19-2
- Add missing files into file section of server package
postgresql-setup v8.6 newly provides postgresql-upgrade
* Tue Nov 30 2021 Filip Januš <fjanus@redhat.com> - 12.9-3
- Add missing files from postgresql-setup v8.6
- Realted: #1935301
* Mon Dec 06 2021 Filip Januš <fjanus@redhat.com> - 10.19-1
- Update to 10.19
- Resolves: CVE-2021-23214
* Mon Nov 29 2021 Marek Kulik <mkulik@redhat.com> - 12.9-2
- Update postgresql-setup to 8.6 (#1935301)
* Mon Nov 29 2021 Marek Kulik <mkulik@redhat.com> - 10.17-4
- Update postgresql-setup to 8.6 (#2024568)
* Mon Nov 15 2021 Filip Januš <fjanus@redhat.com> - 12.9-1
- Update to 12.9
- Resolves: #2007213
* Wed Nov 03 2021 Filip Januš <fjanus@redhat.com> - 10.17-3
- Fix tmp files deprecated path
- Resolves: #1992263
* Fri Nov 05 2021 Filip Januš <fjanus@redhat.com> - 12.7-3
- Using correct path to tmpfiles
- Resolves: #2016991
* Wed Jul 14 2021 Filip Januš <fjanus@redhat.com> - 10.17-2
* Wed Jul 14 2021 Filip Januš <fjanus@redhat.com> - 12.7-2
- Enable ssl for upgrade server
Resolves: #1982701
Resolves: #1981518
* Tue Jun 1 2021 Filip Januš <fjanus@redhat.com> - 10.17-1
- Update to 10.17
Resolves: #1964521
Fix: CVE-2021-32027, CVE-2021-32028
* Tue Jun 1 2021 Filip Januš <fjanus@redhat.com> 12.7-1
- Update to 12.7
Resolves: #1964511
Fix: CVE-2021-32027,CVE-2021-32028
* Wed Nov 18 2020 Patrik Novotný <panovotn@redhat.com> - 10.15-1
- Rebase to upstream release 10.15
Resolves: rhbz#1898214
Resolves: rhbz#1898342
Resolves: rhbz#1898248
* Tue Nov 17 2020 Patrik Novotný <panovotn@redhat.com> - 12.5-1
- Rebase to upstream release 12.5
Resolves: rhbz#1898330
Resolves: rhbz#1898224
Resolves: rhbz#1898244
* Tue Aug 11 2020 Patrik Novotný <panovotn@redhat.com> - 10.14-1
- Rebase to upstream release 10.14
Fixes RHBZ#1727803
Fixes RHBZ#1741489
Fixes RHBZ#1709196
* Tue Nov 26 2019 Patrik Novotný <panovotn@redhat.com> - 12.1-3
- Release bump for 8.2.0 BZ#1776805
* Tue May 12 2020 Patrik Novotný <panovotn@redhat.com> - 10.13-1
- Rebase to upstream release 10.13
Fixes RHBZ#1727803
Fixes RHBZ#1741489
Fixes RHBZ#1709196
* Tue Nov 19 2019 Patrik Novotný <panovotn@redhat.com> - 12.1-2
- Release bump for rebuild against libpq-12.1-3
* Thu Nov 15 2018 Pavel Raiskup <praiskup@redhat.com> - 10.6-1
- update to 10.6 per release notes:
https://www.postgresql.org/docs/10/release-10-6.html
* Tue Nov 12 2019 Patrik Novotný <panovotn@redhat.com> - 12.1-1
- Rebase to upstream release 12.1
* Fri Aug 10 2018 Pavel Raiskup <praiskup@redhat.com> - 10.5-1
* Thu Oct 03 2019 Patrik Novotný <panovotn@redhat.com> - 12.0-1
- Rebase to upstream release 12.0
* Thu Sep 12 2019 Patrik Novotný <panovotn@redhat.com> - 12.0-0.3
- Rebase to upstream beta release 12beta4
- postgresql-server-devel requires krb5-devel
* Thu Aug 08 2019 Petr Kubat <pkubat@redhat.com> - 12.0-0.2
- Rebase to upstream beta release 12beta3
* Wed Jul 03 2019 Patrik Novotný <panovotn@redhat.com> - 12.0-0.1
- Rebase to upstream beta release 12beta2
* Fri May 31 2019 Jitka Plesnikova <jplesnik@redhat.com> - 11.3-2
- Perl 5.30 rebuild
* Thu May 09 2019 Patrik Novotný <panovotn@redhat.com> - 11.3-1
- Rebase to upstream release 11.3
https://www.postgresql.org/docs/11/release-11-3.html
* Tue Mar 05 2019 Pavel Raiskup <praiskup@redhat.com> - 11.2-3
- update postgresql-setup to 8.4 (related to rhbz#1668301)
* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 11.2-2
- Rebuild for readline 8.0
* Thu Feb 14 2019 Patrik Novotný <panovotn@redhat.com> - 11.2-1
- Rebase to upstream release 11.2
* Thu Feb 14 2019 Pavel Raiskup <praiskup@redhat.com> - 11.1-5
- protect against building server against older libpq library
* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 11.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Tue Jan 22 2019 Pavel Raiskup <praiskup@redhat.com> - 11.1-3
- build with ICU support, to provide more opt-in collations
* Mon Jan 14 2019 Björn Esser <besser82@fedoraproject.org> - 11.1-2
- Rebuilt for libcrypt.so.2 (#1666033)
* Wed Nov 07 2018 Patrik Novotný <panovotn@redhat.com> - 11.1-1
- Rebase to upstream release 11.1
https://www.postgresql.org/docs/11/release-11-1.html
* Fri Oct 26 2018 Pavel Raiskup <praiskup@redhat.com> - 11.0-2
- build also contrib *plpython3 modules
* Tue Oct 16 2018 Pavel Raiskup <praiskup@redhat.com> - 11.0-1
- new upstream release, per release notes:
https://www.postgresql.org/docs/11/static/release-11.html
* Wed Sep 05 2018 Pavel Raiskup <praiskup@redhat.com> - 10.5-4
- build without postgresql-libs; libraries moved to libpq and libecpg
* Mon Aug 27 2018 Pavel Raiskup <praiskup@redhat.com> - 10.5-3
- devel subpackage provides postgresql-server-devel and libecpg-devel
(first step for rhbz#1618698)
* Mon Aug 27 2018 Pavel Raiskup <praiskup@redhat.com> - 10.5-2
- packaging cleanup
- devel subpackage to provide libpq-devel (first step for rhbz#1618698)
* Wed Aug 08 2018 Pavel Raiskup <praiskup@redhat.com> - 10.5-1
- update to 10.5 per release notes:
https://www.postgresql.org/docs/10/static/release-10-5.html
* Thu Aug 02 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-4
* Thu Aug 02 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-8
- new postgresql-setup, the %%postgresql_tests* macros now start
the build-time server on random port number
* Wed Aug 01 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-3
- gcc is fixed (rhbz#1600395), dropping the workaround patch
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 10.4-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu Jul 12 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-2
- fix pg_config-*.mo collision with libpq-devel
* Thu Jul 12 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-6
- drop ppc64 patch, gcc is already fixed (rhbz#1544349)
- move pg_config*.mo files into devel subpackage
* Thu Jul 12 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-1
- sync with fedora rawhide
* Mon Jul 09 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-5
- re-enable -O3 for 64bit PPC boxes
- explicitly set PYTHON=python2, /bin/python doesn't exist fc29+
* Tue Jul 03 2018 Petr Pisar <ppisar@redhat.com> - 10.4-4
- Perl 5.28 rebuild
* Wed Jun 27 2018 Jitka Plesnikova <jplesnik@redhat.com> - 10.4-3
- Perl 5.28 rebuild
* Tue Jun 19 2018 Miro Hrončok <mhroncok@redhat.com> - 10.4-2
- Rebuilt for Python 3.7
* Wed May 09 2018 Pavel Raiskup <praiskup@redhat.com> - 10.4-1
- update to 10.4 per release notes:
https://www.postgresql.org/docs/10/static/release-10-4.html
* Thu Apr 26 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-5
- pltcl: drop tcl-pltcl dependency (rhbz#1571181)
* Thu Apr 19 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-4
- fix upgrade subpackage (sync with F28+)
- upgrade: package plpython*.so modules
* Wed Apr 18 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-3
- missing *-devel => *-server-devel* changes (rhbz#1569041)
* Mon Apr 16 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-3
- upgrade: package plperl.so and pltcl.so
- upgrade: package contrib modules
- upgrade: drop dynamic libraries
* Fri Apr 13 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-2
- don't build *-libs subpackage
- don't collide with libpq{,-devel}
- sync with fedora rawhide
- define %%precise_version helper macro
- drop explicit libpq.so provide from *-libs
- update postgresql-setup tarball
- add postgresql-test-rpm-macros package
* Thu Mar 01 2018 Pavel Raiskup <praiskup@redhat.com> - 10.3-1
- update to 10.3 per release notes:
https://www.postgresql.org/docs/10/static/release-10-3.html
* Tue Dec 19 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-2
- build plpython3 subpackage
* Thu Feb 08 2018 Petr Kubat <pkubat@redhat.com> - 10.2-1
- update to 10.2 per release notes:
https://www.postgresql.org/docs/10/static/release-10-2.html
* Tue Dec 19 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-1
- sync with Fedora 28 state
- fix prevmajorversion to 9.2 (RHEL7 version)
- reset Release to 1, for RHEL8 purposes
* Sat Jan 20 2018 Björn Esser <besser82@fedoraproject.org> - 10.1-5
- Rebuilt for switch to libxcrypt
* Tue Dec 19 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-4
- configure with --with-systemd (rhbz#1414314)
- disable startup timeout of PostgreSQL service (rhbz#1525477)
* Wed Dec 13 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-3
- unify %%configure options for python2/python3 configure
- drop --with-krb5 option, not supported since PostgreSQL 9.4
- python packaging - requires/provides s/python/python2/
* Tue Nov 14 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-2
- postgresql-setup v7.0
* Wed Nov 08 2017 Pavel Raiskup <praiskup@redhat.com> - 10.1-1
- update to 10.1 per release notes:
https://www.postgresql.org/docs/10/static/release-10-1.html
* Mon Nov 06 2017 Pavel Raiskup <praiskup@redhat.com> - 10.0-4
- rebase to new postgresql-setup 6.0 version, to fix CVE-2017-15097
* Thu Oct 12 2017 Pavel Raiskup <praiskup@redhat.com> - 10.0-3
- confess that we bundle setup scripts and previous version of ourseleves
- provide %%postgresql_upgrade_prefix macro
* Mon Oct 09 2017 Pavel Raiskup <praiskup@redhat.com> - 10.0-2
- stricter separation of files in upgrade/upgrade-devel
* Mon Oct 09 2017 Jozef Mlich <jmlich@redhat.com> - 10.0-2
- support for upgrade with extenstions
i.e the postgresql-upgrade-devel subpackage was added (rhbz#1475177)
* Fri Oct 06 2017 Pavel Raiskup <praiskup@redhat.com> - 10.0-1
- update to 10.0 per release notes:
https://www.postgresql.org/docs/10/static/release-10.html
* Tue Sep 05 2017 Pavel Raiskup <praiskup@redhat.com> - 9.6.5-2
- move %%_libdir/pgsql into *-libs subpackage
* Tue Aug 29 2017 Pavel Raiskup <praiskup@redhat.com> - 9.6.5-1
- update to 9.6.5 per release notes:
@ -1520,8 +1734,8 @@ make -C postgresql-setup-%{setup_version} check
http://www.postgresql.org/docs/9.3/static/release-9-3-4.html
* Thu Mar 13 2014 Jozef Mlich <jmlich@redhat.com> - 9.3.3-2
- Fix WAL replay of locking an updated tuple
kudos to Alvaro Herrera
- Fix WAL replay of locking an updated tuple
kudos to Alvaro Herrera
* Thu Feb 20 2014 Jozef Mlich <jmlich@redhat.com> - 9.3.3-1
- update to 9.3.3 minor version per release notes:
@ -2311,5 +2525,5 @@ Resolves: #161470
- Default to compiling libpq and ECPG as fully thread-safe
- 7.4 Origin. See previous spec files for previous history. Adapted
- from Red Hat and PGDG's 7.3.4 RPM, directly descended from
- from Red Hat and PGDG's 7.3.4 RPM, directly descended from
- postgresql-7.3.4-2 as shipped in Fedora Core 1.