[PATCH] pgcrypto: Ensure debug handler is reset on error in PGP functions

From: Keyerror Smart <smartkeyerror(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: [PATCH] pgcrypto: Ensure debug handler is reset on error in PGP functions
Date: 2026-08-18 10:42:39
Message-ID: CAD=-kXZOM2eVvCfKgdzzsafTZv0szC+ozwsNaehbwfPxQcp8aw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi, while backporting CVE-2026-14663 to WarehousePG, I found a debug
handler leak issue.

The PGP encryption and decryption functions install a global debug
handler when the "debug=1" option is given, and relied on every error
path explicitly resetting it before throwing. Commit d0ecee6de9a
added an ereport() call in cfb_process() which can fire while the
handler is installed, for example when a cipher fails its deferred
initialization under OpenSSL running in FIPS mode or without the
legacy provider loaded. The error would leave the handler installed
for the remainder of the backend's lifetime, causing subsequent PGP
calls in the same backend to emit "dbg:" NOTICE messages even without
the debug option, until some PGP call happened to complete normally.

CREATE EXTENSION pgcrypto;

-- 1) Trigger: debug=1 installs the global debug handler; blowfish passes
-- pgp_cfb_create() but fails its deferred EVP initialization inside
-- cfb_process(), whose ereport() longjmps past the handler reset.
-- (Requires OpenSSL 3 without the legacy provider, or FIPS mode.)
SELECT pgp_sym_encrypt('x', 'k', 'debug=1, cipher-algo=bf');
-- ERROR: encrypt error: Cipher cannot be initialized

-- 2) The leak becomes visible
SELECT pgp_sym_decrypt('\x00'::bytea, 'k');
-- NOTICE: dbg: pgp_parse_pkt_hdr: not pkt hdr <- leaked handler
-- ERROR: Wrong key or corrupt data

Rather than adding yet another explicit reset at the new error site,
wrap the bodies of encrypt_internal() and decrypt_internal() in
PG_TRY/PG_FINALLY so that the handler is reset no matter how we exit.
This also closes preexisting windows of the same kind, such as an
encoding conversion error or out-of-memory failure occurring while
the handler is installed, and lets us remove the reset calls that
were previously scattered across the success and error paths.

No memory or resource cleanup needs to be moved into the PG_FINALLY
block: all allocations are palloc-based and OpenSSL handles are
tracked by ResourceOwner, so error recovery already takes care of
those.

Attachment Content-Type Size
0001-pgcrypto-Ensure-debug-handler-is-reset-on-error-in-P.patch application/octet-stream 8.1 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Nitin Jadhav 2026-08-18 10:44:24 Re: [WIP] Pipelined Recovery
Previous Message Jakub Wartak 2026-08-18 10:42:12 Re: MPTCP - multiplexing many TCP connections through one socket to get better bandwidth