Skip to content

CVE backports - #411

Open
reshke wants to merge 10 commits into
OPENGPDB_STABLEfrom
cve_backport
Open

reshke wants to merge 10 commits into
OPENGPDB_STABLEfrom
cve_backport

Conversation

@reshke

@reshke reshke commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Here are some reminders before you submit the pull request

  • Add tests for the change
  • Document changes
  • Communicate in the mailing list if needed
  • Pass make installcheck
  • Review a PR in return to support the community

MasahikoSawada and others added 9 commits August 18, 2026 09:28
setup_regexp_matches() sizes the buffer used to convert matched
substrings back from pg_wchar form at the smaller of maxlen*eml and
the original string's byte length, on the assumption that such a
conversion cannot produce more bytes than the string it came
from. That assumption holds only for validly encoded input. But
pg_mb2wchar_with_len() silently accepts bytes that are invalid in the
database encoding, turning each such byte into one pg_wchar, and
converting that back can take more bytes than the input did. A string
made of such bytes therefore overruns the conversion buffer by up to
its own length, corrupting the following memory. regexp_match(),
regexp_matches(), regexp_split_to_table() and regexp_split_to_array()
are all affected.

Fix by dropping the tighter bound and always allocating maxlen*eml + 1
bytes.

Reported-by: Francesco Verardi <frevadiscor89@gmail.com>
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 14
Security: CVE-2026-14664
The CACHESIGN.sign field is a BITVECP, not a TRGM, so you should not
use GETSIGN() on it. You don't get a compiler warning because the
GETSIGN() macro includes a cast. It resulted in a bogus read beyond
end of buffer, which would cause bad split decisions or a crash if
you're very unlucky.

Reported-by: Mehmet D. INCE <mehmet@mehmetince.net>
Backpatch-through: 14
Security: CVE-2026-14678
A grantee of amcheck function EXECUTE privilege could execute arbitrary
functions as the owners of expression indexes that depend on the search
path.  An expression like (lower(col)) was not vulnerable, because
lower() is resolved at CREATE INDEX time.  However, an expression
calling an sql-language or plpgsql-language function often was
vulnerable, even if it used search_path only to find objects in
pg_catalog.  The amcheck documentation has been warning about data
disclosure after such a GRANT, not about function execution.

This might cause new amcheck errors when index expressions rely on a
broader search_path.  Such indexes have seen errors during auto-analyze
since CVE-2018-1058 commit 582edc3, and
v17 amcheck always worked this way.  Hence, the risk is low.

Leave a comment on the one other sandbox entrance that doesn't empty
search_path.  In its case, the choice was valid.

Back-patch to v14 (all supported versions), but v17 was safe already.
Commit 2af07e2f749a9208ca1ed84fa1d8fe0e75833288 (v17) unintentionally
blocked the attack, and commit d70b17636ddf1ea2c71d1c7bc477372b36ccb66b
(v18) unintentionally removed that protection.  Hence, this adds to v17
just a test and a comment.  While emptying search_path became more
widespread in commit 2af07e2f749a9208ca1ed84fa1d8fe0e75833288 (v17),
none of its other changes blocked an attack available in v16, even when
considering GRANT.  For example, brin_summarize_range() has had an owner
check that GRANT does not override.

Reported-by: 王跃林 <violin0613@tju.edu.cn>
Reported-by: Jacob Brazeal <jacob.brazeal@gmail.com>
Backpatch-through: 14
Security: CVE-2026-14673
levenshtein() and levenshtein_less_equal() let the caller specify
the insertion, deletion, and substitution costs, and
fuzzystrmatch's corresponding SQL functions accept any 32-bit
integer for each.  Since the distances are calculated with 32-bit
arithmetic, large costs can cause overflows, thereby producing
nonsensical results.  Certain inputs to levenshtein_less_equal()
can even cause out-of-bounds writes.  To fix, use 64-bit arithmetic
instead, and error whenever the final result won't fit in the
returned 32-bit integer.

We may want to teach these functions to reject negative costs, too,
but that didn't seem appropriate for a security fix, and therefore
it is left as a future exercise.

Reported-by: Ben Morris in collaboration with Claude and Anthropic Research
Author: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Security: CVE-2026-15742
Backpatch-through: 14
This omission allowed roles without USAGE on a type to create range
types that depend on it, which could prevent the owner from
changing the type later.

Reported-by: Jingzhou Fu <fuboat@outlook.com>
Author: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Security: CVE-2026-6470
Backpatch-through: 14
This omission allowed roles without USAGE on a type to create
tables that depend on it, which could prevent the owner from
changing the type later.

Reported-by: Nathan Bossart <nathandbossart@gmail.com>
Author: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Security: CVE-2026-6470
Backpatch-through: 14
PGP encryption was using px_cipher_encrypt without checking if any
error was returned.  When OpenSSL is running in FIPS mode, or when
the legacy provider hasn't been loaded, not all ciphers which are
supported by the PGP code are available and fail the init step in
px_cipher_encrypt.  Since the PGP encryption failed to notice this
it XORed the non-encrypted block with the plaintext, effectively
disabling the encryption.

This was found due to a report of PGP encryption not respecting
the pgcrypto.builtin_crypto_enabled flag and allowing Blowfish
and DES.  This however turned out to be a false positive, since
the PGP code only use ciphers from OpenSSL and not the built in
ciphers.

Bug: #19457
Reported-by: Shishir Sharma <ansh01072001@gmail.com>
Reviewed-by: Jacob Champion <jacob.champion@enterprisedb.com>
Discussion: https://postgr.es/m/19457-4bab15c17aea36c7@postgresql.org
Security: CVE-2026-14663
Backpatch-through: 14
The previous commit raises an ERROR during PGP operations if OpenSSL
does not support the cipher in use. However, any existing messages
created with faulty encryption will no longer be accessible via
pgp_[sym|pub]_decrypt().

To help users out of this situation, add a new ignore-cipher-failure
option which reverts to the broken behavior during decryption only. A
faulty encryption wrapper, created by an OpenSSL configuration that does
not support the cipher, can then be stripped back off by that same
OpenSSL in order to safely reencrypt it. (Note that when OpenSSL does
support the cipher, corrupted messages will not be decrypted regardless
of the ignore-cipher-failure setting; this is unchanged.)

The new tests add a corrupted Blowfish message for both public- and
symmetric-key decryption, resulting in the following test matrix:

- Blowfish supported, default behavior:      fails to decrypt
- Blowfish supported, ignore-cipher-failure: fails to decrypt
- Blowfish unsupported, default behavior:    fails to load cipher
- Blowfish unsupported, ignore-cipher-failure: strips faulty encryption

The previous commit's change to the pubkey tests is expanded similarly:
correctly encrypted messages cannot be decrypted by an OpenSSL that does
not support the cipher, regardless of the option's setting, though the
failure mode will change.

Suggested-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Noah Misch <noah@leadboat.com>
Security: CVE-2026-14663
Backpatch-through: 14
@x4m
x4m requested a review from leborchuk September 18, 2026 06:46
The backported test used syntax unavailable in this 9.4-based branch:
replace plpgsql ASSERT with IF/RAISE EXCEPTION, drop PARALLEL SAFE
from CREATE FUNCTION, and add the GPDB DISTRIBUTED BY notice for
varlena_bug to the expected output.
@leborchuk

Copy link
Copy Markdown
Contributor

LGTM, the overall backport is good enough.

But let's discuss some details, I cannot decide if they are worth fixing or not:

  1. https://www.postgresql.org/support/security/CVE-2026-6470/ was partially fixed.

it does not include 1a358b8f2a2

commit 1a358b8f2a28aaf3a7bfc8cf710de7a39c98436d
Author: Nathan Bossart <nathan@postgresql.org>
Date:   Mon Aug 10 06:38:36 2026 -0700

    Check for USAGE privilege on types used by stored expressions.

    This omission allowed roles without USAGE on a type to create
    stored expressions that depend on it, which could prevent the owner
    from changing the type later.

    The checks deliberately live in the command paths rather than the
    dependency-recording routines.  Those routines also run whenever
    the server re-derives an existing expression, and re-checking there
    would break routine maintenance for an owner who has since lost
    USAGE on a type its objects already reference.  (Checking in the
    dependency-recording routines would also require additional
    CommandCounterIncrement() calls to avoid spurious errors.)

    The addition of a parameter to AlterDomainAddConstraint() breaks
    ABI compatibility, but we are unaware of any impacted third-party
    code.

    Reported-by: Noah Misch <noah@leadboat.com>
    Author: Nathan Bossart <nathandbossart@gmail.com>
    Reviewed-by: Noah Misch <noah@leadboat.com>
    Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
    Reviewed-by: Robert Haas <robertmhaas@gmail.com>
    Security: CVE-2026-6470
    Backpatch-through: 14

Maybe we should take this PR too?

  1. Something strange with pgcrypto tests.

pgp-encrypt_1.out is upstream file while it should be copied from https://github.com/open-gpdb/gpdb/blob/OPENGPDB_STABLE/contrib/pgcrypto/expected/pgp-encrypt.out

Now pgp-encrypt_1.out contains tests never existed in GPDB - for example s2k-count.

But the CI is green. It means something wrong with tests and CI both.

The same with files pgp-decrypt / pgp-pubkey-decrypt. Upstream also touched pgp-decrypt_1.out and pgp-pubkey-decrypt_1.out; this tree has no _1 files at all.

I do not know if we should create pgp-decrypt_1.out since the issue could be with support Blowfish by openSSL. But it's worth investigating.

  1. trgm_gist.c - no need to changed idents. Both else branches were de-indented by one level while making the one-token fix:
-                     else
-                             size_alpha = SIGLENBIT - sizebitvec(
+             else
+                     size_alpha = SIGLENBIT - sizebitvec(
  1. Levenshtein fix ships with zero tests. Upstream added 5 test cases in contrib/fuzzystrmatch/{sql,expected}/fuzzystrmatch.*; this tree's fuzzystrmatch has no regress suite at all, so they were dropped. Why? Maybe it should worth add it.

  2. amcheck fixes should be checked once again, I think we missed some sections while porting it.

Upstream PG 14's contrib/amcheck/sql/check_btree.sql already contained a varlena_bug test block before the CVE fix landed. It was added in 2024 by two unrelated commits that fixed a real amcheck bug:

  • 5df5d9cd7ea — amcheck: Support for different header sizes of short varlena datum (2024-03-23)
  • 4e8529da48b — amcheck: Normalize index tuples containing uncompressed varlena (2024-03-23)
  • (and later af09b18cbad, 2026-06-14, fixing that same code)

Those commits introduced bt_normalize_tuple() in verify_nbtree.c, and the varlena_bug test exists to exercise it.

The CVE-2018-1058 commit — 39d792040c7 — sits directly above that block.

There is no bt_normalize_tuple in current code. Most probably we should also take 5df5d9cd7ea fix

Also, August 2026 batch contains other fixes -

CVE-2026-14662 tsvector/tsquery overflow (2 commits) · 14666 plan-cache invalidation after role changes · 14668 scalarineqsel() const datatype · 14670 PL/Perl tied arrays · 14677 palloc_array() in pltcl/plperl · 14679 FUNC_MAX_ARGS arrays (2 commits) · 14680 type internal functions (2 commits) · 15741 EXTRACT() deparse injection · 16239 portal type cross-check · 16241 ecpg bytea OOB write · 18024 ascii() OOB read · 6464 psql \if/COPY FROM STDIN (2 commits)

Maybe we also could take some of them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants