Commit graph

62208 commits

Author SHA1 Message Date
Tom Lane
de77775a7b Fix some cases of indirectly casting away const.
Newest versions of gcc+glibc are able to detect cases where code
implicitly casts away const by assigning the result of strchr() or
a similar function applied to a "const char *" value to a target
variable that's just "char *".  This of course creates a hazard of
not getting a compiler warning about scribbling on a string one was
not supposed to, so fixing up such cases is good.

This patch fixes a dozen or so places where we were doing that.
Most are trivial additions of "const" to the target variable,
since no actually-hazardous change was occurring.

Thanks to Bertrand Drouvot for finding a couple more spots than
I had.

This commit back-patches relevant portions of 8f1791c61 and
9f7565c6c into supported branches.  However, there are two
places in ecpg (in v18 only) where a proper fix is more
complicated than seems appropriate for a back-patch.  I opted
to silence those two warnings by adding casts.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://postgr.es/m/1324889.1764886170@sss.pgh.pa.us
Discussion: https://postgr.es/m/3988414.1771950285@sss.pgh.pa.us
Backpatch-through: 14-18
2026-02-25 11:19:50 -05:00
Tom Lane
aeaf2fc0dd Stabilize output of new isolation test insert-conflict-do-update-4.
The test added by commit 4b760a181 assumed that a table's physical
row order would be predictable after an UPDATE.  But a non-heap table
AM might produce some other order.  Even with heap AM, the assumption
seems risky; compare a3fd53bab for instance.  Adding an ORDER BY is
cheap insurance and doesn't break any goal of the test.

Author: Pavel Borisov <pashkin.elfe@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CALT9ZEHcE6tpvumScYPO6pGk_ASjTjWojLkodHnk33dvRPHXVw@mail.gmail.com
Backpatch-through: 14
2026-02-25 10:51:42 -05:00
Richard Guo
1c7358099c Fix unsafe RTE_GROUP removal in simplify_EXISTS_query
When simplify_EXISTS_query removes the GROUP BY clauses from an EXISTS
subquery, it previously deleted the RTE_GROUP RTE directly from the
subquery's range table.

This approach is dangerous because deleting an RTE from the middle of
the rtable list shifts the index of any subsequent RTE, which can
silently corrupt any Var nodes in the query tree that reference those
later relations.  (Currently, this direct removal has not caused
problems because the RTE_GROUP RTE happens to always be the last entry
in the rtable list.  However, relying on that is extremely fragile and
seems like trouble waiting to happen.)

Instead of deleting the RTE_GROUP RTE, this patch converts it in-place
to be RTE_RESULT type and clears its groupexprs list.  This preserves
the length and indexing of the rtable list, ensuring all Var
references remain intact.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3472344.1771858107@sss.pgh.pa.us
Backpatch-through: 18
2026-02-25 11:15:05 +09:00
Jacob Champion
1b2773179f pg_upgrade: Use max_protocol_version=3.0 for older servers
The grease patch in 4966bd3ed found its first problem: prior to the
February 2018 patch releases, no server knew how to negotiate protocol
versions, so pg_upgrade needs to take that into account when speaking to
those older servers.

This will be true even after the grease feature is reverted; we don't
need anyone to trip over this again in the future. Backpatch so that all
supported versions of pg_upgrade can gracefully handle an update to the
default protocol version. (This is needed for any distributions that
link older binaries against newer libpqs, such as Debian.) Branches
prior to 18 need an additional version check, for the existence of
max_protocol_version.

Per buildfarm member crake.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOYmi%2B%3D4QhCjssfNEoZVK8LPtWxnfkwT5p-PAeoxtG9gpNjqOQ%40mail.gmail.com
Backpatch-through: 14
2026-02-24 14:01:41 -08:00
Tom Lane
62d6c7d3df Stamp 18.3. 2026-02-23 16:56:43 -05:00
Peter Eisentraut
1598d06b14 Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: 8edd578f1856e2ac142bb3bb7090ec0a58cd8ac6
2026-02-23 13:53:35 +01:00
Tom Lane
24a590112c Release notes for 18.3, 17.9, 16.13, 15.17, 14.22. 2026-02-22 12:22:41 -05:00
Álvaro Herrera
70eca789ea
Update .abi-compliance-history for AddRelationNotNullConstraints().
Commit 8d9a97e0bb anticipated this change:

1 function with incompatible sub-type changes:

  [C] 'function List* AddRelationNotNullConstraints(Relation, List*, List*)' has some sub-type changes:
    parameter 4 of type 'List*' was added

Discussion: https://postgr.es/m/19393-6a82427485a744cf@postgresql.org
Report: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=crake&dt=2026-02-21%2011%3A27%3A03
Backpatch-through: 18 only
2026-02-21 13:08:44 +01:00
Álvaro Herrera
8d9a97e0bb
Avoid name collision with NOT NULL constraints
If a CREATE TABLE statement defined a constraint whose name is identical
to the name generated for a NOT NULL constraint, we'd throw an
(unnecessary) unique key violation error on
pg_constraint_conrelid_contypid_conname_index: this can easily be
avoided by choosing a different name for the NOT NULL constraint.

Fix by passing the constraint names already created by
AddRelationNewConstraints() to AddRelationNotNullConstraints(), so that
the latter can avoid name collisions with them.

Bug: #19393
Author: Laurenz Albe <laurenz.albe@cybertec.at>
Reported-by: Hüseyin Demir <huseyin.d3r@gmail.com>
Backpatch-through: 18
Discussion: https://postgr.es/m/19393-6a82427485a744cf@postgresql.org
2026-02-21 12:22:08 +01:00
Tom Lane
c5edc6c8ff First-draft release notes for 18.3.
As usual, the release notes for other branches will be made by cutting
these down, but put them up for community review first.
2026-02-20 15:31:08 -05:00
Heikki Linnakangas
041e02e6a6 Fix expanding 'bounds' in pg_trgm's calc_word_similarity() function
If the 'bounds' array needs to be expanded, because the input contains
more trigrams than the initial guess, the code didn't return the
reallocated array correctly to the caller. That could lead to a crash
in the rare case that the input string becomes longer when it's
lower-cased. The only known instance of that is when an ICU locale is
used with certain single-byte encodings. This was an oversight in
commit 00896ddaf4.

Author: Zsolt Parragi <zsolt.parragi@percona.com>
Backpatch-through: 18
2026-02-20 11:56:50 +02:00
Richard Guo
ed57c207c3 Fix computation of varnullingrels when translating appendrel Var
When adjust_appendrel_attrs translates a Var referencing a parent
relation into a Var referencing a child relation, it propagates
varnullingrels from the parent Var to the translated Var.  Previously,
the code simply overwrote the translated Var's varnullingrels with
those of the parent.

This was incorrect because the translated Var might already possess
nonempty varnullingrels.  This happens, for example, when a LATERAL
subquery within a UNION ALL references a Var from the nullable side of
an outer join.  In such cases, the translated Var correctly carries
the outer join's relid in its varnullingrels.  Overwriting these bits
with the parent Var's set caused the planner to lose track of the fact
that the Var could be nulled by that outer join.

In the reported case, because the underlying column had a NOT NULL
constraint, the planner incorrectly deduced that the Var could never
be NULL and discarded essential IS NOT NULL filters.  This led to
incorrect query results where NULL rows were returned instead of being
filtered out.

To fix, use bms_add_members to merge the parent Var's varnullingrels
into the translated Var's existing set, preserving both sources of
nullability.

Back-patch to v16.  Although the reported case does not seem to cause
problems in v16, leaving incorrect varnullingrels in the tree seems
like a trap for the unwary.

Bug: #19412
Reported-by: Sergey Shinderuk <s.shinderuk@postgrespro.ru>
Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/19412-1d0318089b86859e@postgresql.org
Backpatch-through: 16
2026-02-20 18:00:02 +09:00
Álvaro Herrera
e3cee403b2
Add translator comment
Otherwise the message is not very clear.

Backpatch-through: 18
2026-02-19 17:11:04 +01:00
Álvaro Herrera
649bd26a40
Update obsolete comment
table_tuple_update's update_indexes argument hasn't been a boolean since
commit 19d8e2308b.

Backpatch-through: 16
2026-02-18 18:09:54 +01:00
Andrew Dunstan
2f6ee7b389 Fix the volatility setting of json{b}_strip_nulls
Commit 4603903d29 unfortunately reset the volatility of these functions
to STABLE whereas they had previously been set to IMMUTABLE. We can't
force a catalog update in the stable release, although a pg_update would
probably do the trick. A simpler fix, though, for affected users is
probably a simple catalog surgery along the lines of:

   UPDATE pg_proc SET provolatile = 'i' WHERE oid in (3261,3262);

Applied to 18 only. In master we are planning to get rid of the separate
redeclarations for defaults in system_functions.sql.

Bug: #19409
Reported-By: Lucio Chiessi <lucio.chiessi@trustly.com>
Discussion: https://postgr.es/m/19409-e16cd2605e59a4af@postgresql.org
2026-02-18 10:31:03 -05:00
Thomas Munro
ccc9be800d Fix test_valid_server_encoding helper function.
Commit c67bef3f32 introduced this test helper function for use by
src/test/regress/sql/encoding.sql, but its logic was incorrect.  It
confused an encoding ID for a boolean so it gave the wrong results for
some inputs, and also forgot the usual return macro.  The mistake didn't
affect values actually used in the test, so there is no change in
behavior.

Also drop it and another missed function at the end of the test, for
consistency.

Backpatch-through: 14
Author: Zsolt Parragi <zsolt.parragi@percona.com>
2026-02-17 16:36:59 +13:00
Noah Misch
d04b34d685 Suppress new "may be used uninitialized" warning.
Various buildfarm members, having compilers like gcc 8.5 and 6.3, fail
to deduce that text_substring() variable "E" is initialized if
slice_size!=-1.  This suppression approach quiets gcc 8.5; I did not
reproduce the warning elsewhere.  Back-patch to v14, like commit
9f4fd119b2.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1157953.1771266105@sss.pgh.pa.us
Backpatch-through: 14
2026-02-16 18:05:01 -08:00
Michael Paquier
4a0843c539 hstore: Fix NULL pointer dereference with receive function
The receive function of hstore was not able to handle correctly
duplicate key values when a new duplicate links to a NULL value, where a
pfree() could be attempted on a NULL pointer, crashing due to a pointer
dereference.

This problem would happen for a COPY BINARY, when stacking values like
that:
aa => 5
aa => null

The second key/value pair is discarded and pfree() calls are attempted
on its key and its value, leading to a pointer dereference for the value
part as the value is NULL.  The first key/value pair takes priority when
a duplicate is found.

Per offline report.

Reported-by: "Anemone" <vergissmeinnichtzh@gmail.com>
Reported-by: "A1ex" <alex000young@gmail.com>
Backpatch-through: 14
2026-02-17 08:41:30 +09:00
Heikki Linnakangas
817f74600d Don't reset 'latest_page_number' when replaying multixid truncation
'latest_page_number' is set to the correct value, according to
nextOffset, early at system startup. Contrary to the comment, it hence
should be set up correctly by the time we get to WAL replay.

This fixes a failure to replay WAL generated on older minor versions,
before commit 789d65364c (18.2, 17.8, 16.12, 15.16, 14.21). The
failure occurs after a truncation record has been replayed and looks
like this:

    FATAL:  could not access status of transaction 858112
    DETAIL:  Could not read from file "pg_multixact/offsets/000D" at offset 24576: read too few bytes.
    CONTEXT:  WAL redo at 3/2A3AB408 for MultiXact/CREATE_ID: 858111 offset 6695072 nmembers 5: 1048228 (sh) 1048271 (keysh) 1048316 (sh) 1048344 (keysh) 1048370 (sh)

Reported-by: Sebastian Webber <sebastian@swebber.me>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Discussion: https://www.postgresql.org/message-id/20260214090150.GC2297@p46.dedyn.io;lightning.p46.dedyn.io
Backpatch-through: 14-18
2026-02-16 17:16:59 +02:00
Michael Paquier
770d13dd06 pgcrypto: Tweak error message for incorrect session key length
The error message added in 379695d3cc referred to the public key being
too long.  This is confusing as it is in fact the session key included
in a PGP message which is too long.  This is harmless, but let's be
precise about what is wrong.

Per offline report.

Reported-by: Zsolt Parragi <zsolt.parragi@percona.com>
Backpatch-through: 14
2026-02-16 12:18:28 +09:00
Noah Misch
6e045e1a6e Fix SUBSTRING() for toasted multibyte characters.
Commit 1e7fe06c10 changed
pg_mbstrlen_with_len() to ereport(ERROR) if the input ends in an
incomplete character.  Most callers want that.  text_substring() does
not.  It detoasts the most bytes it could possibly need to get the
requested number of characters.  For example, to extract up to 2 chars
from UTF8, it needs to detoast 8 bytes.  In a string of 3-byte UTF8
chars, 8 bytes spans 2 complete chars and 1 partial char.

Fix this by replacing this pg_mbstrlen_with_len() call with a string
traversal that differs by stopping upon finding as many chars as the
substring could need.  This also makes SUBSTRING() stop raising an
encoding error if the incomplete char is past the end of the substring.
This is consistent with the general philosophy of the above commit,
which was to raise errors on a just-in-time basis.  Before the above
commit, SUBSTRING() never raised an encoding error.

SUBSTRING() has long been detoasting enough for one more char than
needed, because it did not distinguish exclusive and inclusive end
position.  For avoidance of doubt, stop detoasting extra.

Back-patch to v14, like the above commit.  For applications using
SUBSTRING() on non-ASCII column values, consider applying this to your
copy of any of the February 12, 2026 releases.

Reported-by: SATŌ Kentarō <ranvis@gmail.com>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Bug: #19406
Discussion: https://postgr.es/m/19406-9867fddddd724fca@postgresql.org
Backpatch-through: 14
2026-02-14 12:16:19 -08:00
Noah Misch
4174e41b9e pg_mblen_range, pg_mblen_with_len: Valgrind after encoding ereport.
The prior order caused spurious Valgrind errors.  They're spurious
because the ereport(ERROR) non-local exit discards the pointer in
question.  pg_mblen_cstr() ordered the checks correctly, but these other
two did not.  Back-patch to v14, like commit
1e7fe06c10.

Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/20260214053821.fa.noahmisch@microsoft.com
Backpatch-through: 14
2026-02-14 12:16:19 -08:00
Michael Paquier
5b0e0c3d03 Improve error message for checksum failures in pgstat_database.c
This log message was referring to conflicts, but it is about checksum
failures.  The log message improved in this commit should never show up,
due to the fact that pgstat_prepare_report_checksum_failure() should
always be called before pgstat_report_checksum_failures_in_db(), with a
stats entry already created in the pgstats shared hash table.  The three
code paths able to report database-level checksum failures follow
already this requirement.

Oversight in b96d3c3897.

Author: Wang Peng <215722532@qq.com>
Discussion: https://postgr.es/m/tencent_9B6CD6D9D34AE28CDEADEC6188DB3BA1FE07@qq.com
Backpatch-through: 18
2026-02-13 12:17:12 +09:00
Heikki Linnakangas
b08033944e Make pg_numa_query_pages() work in frontend programs
It's currently only used in the server, but it was placed in src/port
with the idea that it might be useful in client programs too. However,
it will currently fail to link if used in a client program, because
CHECK_FOR_INTERRUPTS() is not usable in client programs. Fix that by
wrapping it in "#ifndef FRONTEND".

Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://www.postgresql.org/message-id/21cc7a48-99d9-4f69-9a3f-2c2de61ac8e5%40iki.fi
Backpatch-through: 18
2026-02-12 19:41:29 +02:00
Tom Lane
ce4b7e3a10 Fix plpgsql's handling of "return simple_record_variable".
If the variable's value is null, exec_stmt_return() missed filling
in estate->rettype.  This is a pretty old bug, but we'd managed not
to notice because that value isn't consulted for a null result ...
unless we have to cast it to a domain.  That case led to a failure
with "cache lookup failed for type 0".

The correct way to assign the data type is known by exec_eval_datum.
While we could copy-and-paste that logic, it seems like a better
idea to just invoke exec_eval_datum, as the ROW case already does.

Reported-by: Pavel Stehule <pavel.stehule@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAFj8pRBT_ahexDf-zT-cyH8bMR_qcySKM8D5nv5MvTWPiatYGA@mail.gmail.com
Backpatch-through: 14
2026-02-11 16:53:14 -05:00
Heikki Linnakangas
53463b4b24 Fix pg_stat_get_backend_wait_event() for aux processes
The pg_stat_activity view shows information for aux processes, but the
pg_stat_get_backend_wait_event() and
pg_stat_get_backend_wait_event_type() functions did not. To fix, call
AuxiliaryPidGetProc(pid) if BackendPidGetProc(pid) returns NULL, like
we do in pg_stat_get_activity().

In version 17 and above, it's a little silly to use those functions
when we already have the ProcNumber at hand, but it was necessary
before v17 because the backend ID was different from ProcNumber. I
have other plans for wait_event_info on master, so it doesn't seem
worth applying a different fix on different versions now.

Reviewed-by: Sami Imseih <samimseih@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://www.postgresql.org/message-id/c0320e04-6e85-4c49-80c5-27cfb3a58108@iki.fi
Backpatch-through: 14
2026-02-11 18:51:06 +02:00
Tom Lane
946b653b7a Further stabilize a postgres_fdw test case.
The buildfarm occasionally shows a variant row order in the output
of this UPDATE ... RETURNING, implying that the preceding INSERT
dropped one of the rows into some free space within the table rather
than appending them all at the end.  It's not entirely clear why that
happens some times and not other times, but we have established that
it's affected by concurrent activity in other databases of the
cluster.  In any case, the behavior is not wrong; the test is at fault
for presuming that a seqscan will give deterministic row ordering.
Add an ORDER BY atop the update to stop the buildfarm noise.

The buildfarm seems to have shown this only in v18 and master
branches, but just in case the cause is older, back-patch to
all supported branches.

Discussion: https://postgr.es/m/3866274.1770743162@sss.pgh.pa.us
Backpatch-through: 14
2026-02-11 11:03:01 -05:00
Dean Rasheed
7233e70537 doc: Mention all SELECT privileges required by INSERT ... ON CONFLICT.
On the INSERT page, mention that SELECT privileges are also required
for any columns mentioned in the arbiter clause, including those
referred to by the constraint, and clarify that this applies to all
forms of ON CONFLICT, not just ON CONFLICT DO UPDATE.

Author: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Viktor Holmberg <v@viktorh.net>
Discussion: https://postgr.es/m/CAEZATCXGwMQ+x00YY9XYG46T0kCajH=21QaYL9Xatz0dLKii+g@mail.gmail.com
Backpatch-through: 14
2026-02-11 10:52:59 +00:00
Dean Rasheed
dfc15bd328 doc: Clarify RLS policies applied for ON CONFLICT DO NOTHING.
On the CREATE POLICY page, the description of per-command policies
stated that SELECT policies are applied when an INSERT has an ON
CONFLICT DO NOTHING clause. However, that is only the case if it
includes an arbiter clause, so clarify that.

While at it, also clarify the comment in the regression tests that
cover this.

Author: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Viktor Holmberg <v@viktorh.net>
Discussion: https://postgr.es/m/CAEZATCXGwMQ+x00YY9XYG46T0kCajH=21QaYL9Xatz0dLKii+g@mail.gmail.com
Backpatch-through: 14
2026-02-11 10:25:06 +00:00
Tom Lane
5a461dc4db Stamp 18.2. 2026-02-09 16:49:49 -05:00
Tom Lane
30d2603f5c Last-minute updates for release notes.
Security: CVE-2026-2003, CVE-2026-2004, CVE-2026-2005, CVE-2026-2006, CVE-2026-2007
2026-02-09 14:01:20 -05:00
Noah Misch
4543b02af3 Fix test "NUL byte in text decrypt" for --without-zlib builds.
Backpatch-through: 14
Security: CVE-2026-2006
2026-02-09 09:08:13 -08:00
Tom Lane
b69af3dda2 Harden _int_matchsel() against being attached to the wrong operator.
While the preceding commit prevented such attachments from occurring
in future, this one aims to prevent further abuse of any already-
created operator that exposes _int_matchsel to the wrong data types.
(No other contrib module has a vulnerable selectivity estimator.)

We need only check that the Const we've found in the query is indeed
of the type we expect (query_int), but there's a difficulty: as an
extension type, query_int doesn't have a fixed OID that we could
hard-code into the estimator.

Therefore, the bulk of this patch consists of infrastructure to let
an extension function securely look up the OID of a datatype
belonging to the same extension.  (Extension authors have requested
such functionality before, so we anticipate that this code will
have additional non-security uses, and may soon be extended to allow
looking up other kinds of SQL objects.)

This is done by first finding the extension that owns the calling
function (there can be only one), and then thumbing through the
objects owned by that extension to find a type that has the desired
name.  This is relatively expensive, especially for large extensions,
so a simple cache is put in front of these lookups.

Reported-by: Daniel Firer as part of zeroday.cloud
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Noah Misch <noah@leadboat.com>
Security: CVE-2026-2004
Backpatch-through: 14
2026-02-09 10:14:22 -05:00
Tom Lane
66ddac6982 Require superuser to install a non-built-in selectivity estimator.
Selectivity estimators come in two flavors: those that make specific
assumptions about the data types they are working with, and those
that don't.  Most of the built-in estimators are of the latter kind
and are meant to be safely attachable to any operator.  If the
operator does not behave as the estimator expects, you might get a
poor estimate, but it won't crash.

However, estimators that do make datatype assumptions can malfunction
if they are attached to the wrong operator, since then the data they
get from pg_statistic may not be of the type they expect.  This can
rise to the level of a security problem, even permitting arbitrary
code execution by a user who has the ability to create SQL objects.

To close this hole, establish a rule that built-in estimators are
required to protect themselves against being called on the wrong type
of data.  It does not seem practical however to expect estimators in
extensions to reach a similar level of security, at least not in the
near term.  Therefore, also establish a rule that superuser privilege
is required to attach a non-built-in estimator to an operator.
We expect that this restriction will have little negative impact on
extensions, since estimators generally have to be written in C and
thus superuser privilege is required to create them in the first
place.

This commit changes the privilege checks in CREATE/ALTER OPERATOR
to enforce the rule about superuser privilege, and fixes a couple
of built-in estimators that were making datatype assumptions without
sufficiently checking that they're valid.

Reported-by: Daniel Firer as part of zeroday.cloud
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Noah Misch <noah@leadboat.com>
Security: CVE-2026-2004
Backpatch-through: 14
2026-02-09 10:07:31 -05:00
Tom Lane
3b6588cd90 Guard against unexpected dimensions of oidvector/int2vector.
These data types are represented like full-fledged arrays, but
functions that deal specifically with these types assume that the
array is 1-dimensional and contains no nulls.  However, there are
cast pathways that allow general oid[] or int2[] arrays to be cast
to these types, allowing these expectations to be violated.  This
can be exploited to cause server memory disclosure or SIGSEGV.
Fix by installing explicit checks in functions that accept these
types.

Reported-by: Altan Birler <altan.birler@tum.de>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Noah Misch <noah@leadboat.com>
Security: CVE-2026-2003
Backpatch-through: 14
2026-02-09 09:57:44 -05:00
Noah Misch
b427091947 Require PGP-decrypted text to pass encoding validation.
pgp_sym_decrypt() and pgp_pub_decrypt() will raise such errors, while
bytea variants will not.  The existing "dat3" test decrypted to non-UTF8
text, so switch that query to bytea.

The long-term intent is for type "text" to always be valid in the
database encoding.  pgcrypto has long been known as a source of
exceptions to that intent, but a report about exploiting invalid values
of type "text" brought this module to the forefront.  This particular
exception is straightforward to fix, with reasonable effect on user
queries.  Back-patch to v14 (all supported versions).

Reported-by: Paul Gerste (as part of zeroday.cloud)
Reported-by: Moritz Sanft (as part of zeroday.cloud)
Author: shihao zhong <zhong950419@gmail.com>
Reviewed-by: cary huang <hcary328@gmail.com>
Discussion: https://postgr.es/m/CAGRkXqRZyo0gLxPJqUsDqtWYBbgM14betsHiLRPj9mo2=z9VvA@mail.gmail.com
Backpatch-through: 14
Security: CVE-2026-2006
2026-02-09 06:14:50 -08:00
Thomas Munro
b0f5d25bc3 Code coverage for most pg_mblen* calls.
A security patch changed them today, so close the coverage gap now.
Test that buffer overrun is avoided when pg_mblen*() requires more
than the number of bytes remaining.

This does not cover the calls in dict_thesaurus.c or in dict_synonym.c.
That code is straightforward.  To change that code's input, one must
have access to modify installed OS files, so low-privilege users are not
a threat.  Testing this would likewise require changing installed
share/postgresql/tsearch_data, which was enough of an obstacle to not
bother.

Security: CVE-2026-2006
Backpatch-through: 14
Co-authored-by: Thomas Munro <thomas.munro@gmail.com>
Co-authored-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
2026-02-09 12:43:50 +13:00
Thomas Munro
7b5fc85bef Replace pg_mblen() with bounds-checked versions.
A corrupted string could cause code that iterates with pg_mblen() to
overrun its buffer.  Fix, by converting all callers to one of the
following:

1. Callers with a null-terminated string now use pg_mblen_cstr(), which
raises an "illegal byte sequence" error if it finds a terminator in the
middle of the sequence.

2. Callers with a length or end pointer now use either
pg_mblen_with_len() or pg_mblen_range(), for the same effect, depending
on which of the two seems more convenient at each site.

3. A small number of cases pre-validate a string, and can use
pg_mblen_unbounded().

The traditional pg_mblen() function and COPYCHAR macro still exist for
backward compatibility, but are no longer used by core code and are
hereby deprecated.  The same applies to the t_isXXX() functions.

Security: CVE-2026-2006
Backpatch-through: 14
Co-authored-by: Thomas Munro <thomas.munro@gmail.com>
Co-authored-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reported-by: Paul Gerste (as part of zeroday.cloud)
Reported-by: Moritz Sanft (as part of zeroday.cloud)
2026-02-09 12:43:42 +13:00
Thomas Munro
efef05ba99 Fix mb2wchar functions on short input.
When converting multibyte to pg_wchar, the UTF-8 implementation would
silently ignore an incomplete final character, while the other
implementations would cast a single byte to pg_wchar, and then repeat
for the remaining byte sequence.  While it didn't overrun the buffer, it
was surely garbage output.

Make all encodings behave like the UTF-8 implementation.  A later change
for master only will convert this to an error, but we choose not to
back-patch that behavior change on the off-chance that someone is
relying on the existing UTF-8 behavior.

Security: CVE-2026-2006
Backpatch-through: 14
Author: Thomas Munro <thomas.munro@gmail.com>
Reported-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
2026-02-09 12:12:33 +13:00
Thomas Munro
df0852fe03 Fix encoding length for EUC_CN.
While EUC_CN supports only 1- and 2-byte sequences (CS0, CS1), the
mb<->wchar conversion functions allow 3-byte sequences beginning SS2,
SS3.

Change pg_encoding_max_length() to return 3, not 2, to close a
hypothesized buffer overrun if a corrupted string is converted to wchar
and back again in a newly allocated buffer.  We might reconsider that in
master (ie harmonizing in a different direction), but this change seems
better for the back-branches.

Also change pg_euccn_mblen() to report SS2 and SS3 characters as having
length 3 (following the example of EUC_KR).  Even though such characters
would not pass verification, it's remotely possible that invalid bytes
could be used to compute a buffer size for use in wchar conversion.

Security: CVE-2026-2006
Backpatch-through: 14
Author: Thomas Munro <thomas.munro@gmail.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
2026-02-09 12:12:29 +13:00
Heikki Linnakangas
e0965fb1a8 Fix buffer overflows in pg_trgm due to lower-casing
The code made a subtle assumption that the lower-cased version of a
string never has more characters than the original. That is not always
true. For example, in a database with the latin9 encoding:

    latin9db=# select lower(U&'\00CC' COLLATE "lt-x-icu");
       lower
    -----------
     i\x1A\x1A
    (1 row)

In this example, lower-casing expands the single input character into
three characters.

The generate_trgm_only() function relied on that assumption in two
ways:

- It used "slen * pg_database_encoding_max_length() + 4" to allocate
  the buffer to hold the lowercased and blank-padded string. That
  formula accounts for expansion if the lower-case characters are
  longer (in bytes) than the originals, but it's still not enough if
  the lower-cased string contains more *characters* than the original.

- Its callers sized the output array to hold the trigrams extracted
  from the input string with the formula "(slen / 2 + 1) * 3", where
  'slen' is the input string length in bytes. (The formula was
  generous to account for the possibility that RPADDING was set to 2.)
  That's also not enough if one input byte can turn into multiple
  characters.

To fix, introduce a growable trigram array and give up on trying to
choose the correct max buffer sizes ahead of time.

Backpatch to v18, but no further. In previous versions lower-casing was
done character by character, and thus the assumption that lower-casing
doesn't change the character length was valid. That was changed in v18,
commit fb1a18810f.

Security: CVE-2026-2007
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Jeff Davis <pgsql@j-davis.com>
2026-02-09 12:12:24 +13:00
Heikki Linnakangas
18548681da Remove 'charlen' argument from make_trigrams()
The function assumed that if charlen == bytelen, there are no
multibyte characters in the string. That's sensible, but the callers
were a little careless in how they calculated the lengths. The callers
converted the string to lowercase before calling make_trigram(), and
the 'charlen' value was calculated *before* the conversion to
lowercase while 'bytelen' was calculated after the conversion. If the
lowercased string had a different number of characters than the
original, make_trigram() might incorrectly apply the fastpath and
treat all the bytes as single-byte characters, or fail to apply the
fastpath (which is harmless), or it might hit the "Assert(bytelen ==
charlen)" assertion. I'm not aware of any locale / character
combinations where you could hit that assertion in practice,
i.e. where a string converted to lowercase would have fewer characters
than the original, but it seems best to avoid making that assumption.

To fix, remove the 'charlen' argument. To keep the performance when
there are no multibyte characters, always try the fast path first, but
check the input for multibyte characters as we go. The check on each
byte adds some overhead, but it's close enough. And to compensate, the
find_word() function no longer needs to count the characters.

This fixes one small bug in make_trigrams(): in the multibyte
codepath, it peeked at the byte just after the end of the input
string. When compiled with IGNORECASE, that was harmless because there
is always a NUL byte or blank after the input string. But with
!IGNORECASE, the call from generate_wildcard_trgm() doesn't guarantee
that.

Backpatch to v18, but no further. In previous versions lower-casing was
done character by character, and thus the assumption that lower-casing
doesn't change the character length was valid. That was changed in v18,
commit fb1a18810f.

Security: CVE-2026-2007
Reviewed-by: Noah Misch <noah@leadboat.com>
2026-02-09 12:12:18 +13:00
Michael Paquier
209f387b81 pgcrypto: Fix buffer overflow in pgp_pub_decrypt_bytea()
pgp_pub_decrypt_bytea() was missing a safeguard for the session key
length read from the message data, that can be given in input of
pgp_pub_decrypt_bytea().  This can result in the possibility of a buffer
overflow for the session key data, when the length specified is longer
than PGP_MAX_KEY, which is the maximum size of the buffer where the
session data is copied to.

A script able to rebuild the message and key data that can trigger the
overflow is included in this commit, based on some contents provided by
the reporter, heavily editted by me.  A SQL test is added, based on the
data generated by the script.

Reported-by: Team Xint Code as part of zeroday.cloud
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Noah Misch <noah@leadboat.com>
Security: CVE-2026-2005
Backpatch-through: 14
2026-02-09 08:01:05 +09:00
Tom Lane
5944beb739 Release notes for 18.2, 17.8, 16.12, 15.16, 14.21. 2026-02-08 13:00:40 -05:00
Peter Eisentraut
731e03272e Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: bdee668bac7ab3256b6f922c0b6fb663a3b03e16
2026-02-08 15:07:02 +01:00
Tom Lane
5eac1d68fc meson: host_system value for Solaris is 'sunos' not 'solaris'.
This thinko caused us to not substitute our own getopt() code,
which results in failing to parse long options for the postmaster
since Solaris' getopt() doesn't do what we expect.  This can be seen
in the results of buildfarm member icarus, which is the only one
trying to build via meson on Solaris.

Per consultation with pgsql-release, it seems okay to fix this
now even though we're in release freeze.  The fix visibly won't
affect any other platforms, and it can't break Solaris/meson
builds any worse than they're already broken.

Discussion: https://postgr.es/m/2471229.1770499291@sss.pgh.pa.us
Backpatch-through: 16
2026-02-07 20:05:52 -05:00
Peter Eisentraut
cff2ef9845 Further error message fix
Further fix of error message changed in commit 74a116a79b.  The
initial fix was not quite correct.

Discussion: https://www.postgresql.org/message-id/flat/tencent_1EE1430B1E6C18A663B8990F%40qq.com
2026-02-07 22:53:16 +01:00
Thomas Munro
3c3b34bbee Placate ABI checker.
It's not really an ABI break if you change the layout/size of an object
with incomplete type, as commit f94e9141 did, so advance the ABI
compliance reference commit in 16-18 to satisfy build farm animal crake.

Backpatch-through: 16-18
Discussion: https://www.postgresql.org/message-id/1871492.1770409863%40sss.pgh.pa.us
2026-02-07 11:47:57 +13:00
Tom Lane
c6881f7922 First-draft release notes for 18.2.
As usual, the release notes for other branches will be made by cutting
these down, but put them up for community review first.
2026-02-06 13:06:16 -05:00
Michael Paquier
e679d0f0b6 Fix use of proc number in pgstat_create_backend()
This routine's internals directly used MyProcNumber to choose which
object ID to assign for the hash key of a backend's stats entry, while
the value to use is given as input argument of the function.

The original intention was to pass MyProcNumber as an argument of
pgstat_create_backend() when called in pgstat_bestart_final(),
pgstat_beinit() ensuring that MyProcNumber has been set, not use it
directly in the function.  This commit addresses this inconsistency by
using the procnum given by the caller of pgstat_create_backend(), not
MyProcNumber.

This issue is not a cause of bugs currently.  However, let's keep the
code in sync across all the branches where this code exists, as it could
matter in a future backpatch.

Oversight in 4feba03d8b.

Reported-by: Ryo Matsumura <matsumura.ryo@fujitsu.com>
Discussion: https://postgr.es/m/TYCPR01MB11316AD8150C8F470319ACCAEE866A@TYCPR01MB11316.jpnprd01.prod.outlook.com
Backpatch-through: 18
2026-02-06 19:57:26 +09:00