On this page · 6 sections
  1. What Happens Past 32767 Parameters
  2. Replacing Long Parameter Lists With One Array Parameter
  3. Upgrading psqlODBC
  4. Two Other Fixes in 18.00.0005
  5. Verification Checklist After the Upgrade
  6. Sources

Security advisory

Status as of 2026-11-13

CVE-2026-109448

PostgreSQL psqlODBC · psqlODBC SQLBindParameter heap memory corruption when binding more than 32767 parameters

CVSS 3.15.9Medium
Affected
from 08.01.0102 before 18.00.0005
First fixed in
18.00.0005The earliest release on each line that fixes these CVEs. The release to install is in the article's upgrade steps.
Exploited
None known · CISA SSVC
Published
2026-10-12

Data: CVE record

Every application that reaches PostgreSQL through psqlODBC, the official ODBC driver, from version 08.01.0102 through 18.00.0004 should move to psqlODBC 18.00.0005 or later. The release fixes CVE-2026-109448: the driver kept the number of bound parameters in a signed 16-bit field, so binding more than 32767 parameters on one statement corrupted heap memory. Applications most at risk are those that build a parameter list from user input, such as an IN (?, ?, ...) list, and those are also the ones that need a code change to keep working after the upgrade.

What Happens Past 32767 Parameters #

The advisory GHSA-cmfx-rm3r-p2jr explains the arithmetic. SQLBindParameter accepted parameter numbers from 1 to 65535, but the count lived in a signed 16-bit field. Binding parameter 32768 wraps the count to -32768; binding parameter 32769 then grows the binding arrays and zero-fills them from index -32768, writing about 2.5 MB of zeros that start 1.25 MB before the allocation. At exactly 32768 parameters nothing is corrupted, but execution fails with SQLSTATE 07002 even though every parameter was bound, which is why the release announcement speaks of "more than 32768" and the advisory title of "more than 32767".

The symptom depends on the allocator. Glibc builds abort with realloc(): invalid next size, Windows standard builds fail with an access violation, 0xC0000005, and other allocators, including the Windows mimalloc builds, can keep running on a corrupted heap and crash later. The CVSS 3.1 score of 5.9, Medium, from the PostgreSQL CNA reflects that the impact is on availability only; the weaknesses are CWE-190 and CWE-124. CISA's SSVC assessment rates exploitation as none.

Warning

From 18.00.0005 on, SQLBindParameter rejects parameter numbers outside 1 to 32767 with SQLSTATE 07009, invalid descriptor index. Code that used to crash on a huge parameter list now gets an error instead, so a query built from an unbounded user list fails loudly until the application stops binding that many parameters. The announcement notes that no earlier release could run a statement with more than 32767 parameters, so nothing that worked before breaks.

Replacing Long Parameter Lists With One Array Parameter #

The old way builds one placeholder per value, so the parameter count grows with the input:

SQL
-- one ? per user-supplied id: 40000 ids means 40000 parameters
SELECT * FROM orders WHERE customer_id IN (?, ?, ?, ...);

The new way, which the advisory recommends as a workaround, passes the whole list as a single array parameter, so the statement always has one parameter:

SQL
-- one array parameter, for example '{17,42,99}' bound as text
SELECT * FROM orders WHERE customer_id = ANY(?::int[]);

Upgrading psqlODBC #

  1. Find every host and image that loads psqlODBC, including Windows machines that use it through ADO or other OLE DB consumers, and note the installed version.
  2. Install 18.00.0005 or later. Windows installers and merge modules for x86, x64 and ARM64 are on the PostgreSQL download site and the GitHub release page; the Windows packages are now built with OpenSSL 3.5.9.
  3. Before or alongside the upgrade, cap the number of parameters any statement builds from external input, or switch those queries to a single array parameter as shown above.
  4. Handle SQLSTATE 07009 from SQLBindParameter in code paths that bind a variable number of parameters, so an oversized request returns an error to the caller instead of an unexplained failure.
  5. Check statements that bind 1000 or more parameters on the server: the same release fixes a bug that truncated type names after parameter 1000, causing errors such as type "timestam" does not exist.

Two Other Fixes in 18.00.0005 #

Besides the prepared-statement type name bug, 18.00.0005 fixes bytea parameters that failed with "Type is invalid" through Microsoft's OLE DB Provider for ODBC, MSDASQL, since 18.00.0003. The psqlODBC team credits Richard Kuesters with reporting the security issue.

Verification Checklist After the Upgrade #

  • The ODBC driver manager or the installed package reports psqlODBC 18.00.0005 or later on every host.
  • No query path binds a parameter count taken directly from user input without an upper limit.
  • Large value lists reach PostgreSQL as one array parameter with = ANY(?).
  • Application logs no longer show realloc(): invalid next size or 0xC0000005 crashes from the driver.
  • Code paths that bind many parameters handle SQLSTATE 07009.

The Sentinel’s Call

Every application on psqlODBC 18.00.0004 or earlier should move to 18.00.0005 or later, and first those that build IN lists from user input, since one oversized request could corrupt the heap. Switching such lists to a single array parameter removes the problem on any driver version. After the upgrade, an oversized list returns SQLSTATE 07009 instead of crashing.

Our judgement, drawn only from the facts and sources above.

Sources

  1. GHSA-cmfx-rm3r-p2jr: Heap memory corruption when binding more than 32767 parameters github.com · Oct 12, 2026
  2. PostgreSQL: psqlODBC 18.00.0005 released with security fix for CVE-2026-109448 postgresql.org · Oct 14, 2026
  3. CVE-2026-109448: psqlODBC SQLBindParameter heap memory corruption when binding more than 32767 parameters cve.org · Oct 12, 2026

More on PostgreSQL

1 other article, newest first

Next reading

Edited and approved by Jarosław Krzemiński. Spotted a mistake? Report a correction or read the corrections policy.