Re: BUG #19511: contrib/dblink: NULL dereference in dblink_get_notify() when called without a prior connection

From: Amjad Shahzad <amjadshahzad2000(at)gmail(dot)com>
To: amjadshahzad2000(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19511: contrib/dblink: NULL dereference in dblink_get_notify() when called without a prior connection
Date: 2026-06-05 01:19:48
Message-ID: CADHzGZRAxFYoxMC+g6pEJ0FL0bfVhFi+y0jQ0cRNCC5hFjvJ3Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi

This was originally reported to security(at)postgresql(dot)org, redirected here by
the security team as this does not meet the security
vulnerability threshold.

Patch attached. Applies cleanly against master 0392fb900eb.
Adds the same NULL guard used by every other function in dblink.c that
accesses the default connection.

Regards
Amjad

On Fri, Jun 5, 2026 at 6:16 AM PG Bug reporting form <noreply(at)postgresql(dot)org>
wrote:

> The following bug has been logged on the website:
>
> Bug reference: 19511
> Logged by: Amjad Shahzad
> Email address: amjadshahzad2000(at)gmail(dot)com
> PostgreSQL version: 18.4
> Operating system: Ubuntu 24.04 x86_64
> Description:
>
> I found a NULL pointer dereference in contrib/dblink/dblink.c in the
> dblink_get_notify() function. Any user with EXECUTE on the function
> can crash their backend process with a single call. Confirmed against
> master
> commit 0392fb900eb.
>
> WHAT IS THE ISSUE
> =================
> dblink_get_notify() retrieves async notifications from a remote connection.
> When called with no arguments it uses the default
> (unnamed) connection. If no default connection has been established first,
> pconn->conn is NULL. The code assigns this NULL to conn and
> then passes it directly to PQconsumeInput() and PQnotifies():
>
> /* line 1893 (master) */
> else
> conn = pconn->conn; /* NULL — no connection established */
>
> InitMaterializedSRF(fcinfo, 0);
>
> PQconsumeInput(conn); /* passes NULL to libpq */
> while ((notify = PQnotifies(conn)) != NULL) /* NULL dereference */
>
> PQnotifies(NULL) dereferences a null pointer internally, causing a backend
> SIGSEGV.
>
> Every other function in dblink.c that uses the default connection already
> has an explicit NULL guard:
>
> if (!conn)
> dblink_conn_not_avail(conname);
>
> dblink_get_notify() is the only function that skips this guard.
>
> WHAT CAN BE COMPROMISED
> =========================
> Any user with EXECUTE on dblink_get_notify(), granted to PUBLIC by default
> can crash their backend process
> on demand. No password, no connection, no special privileges required.
>
> In a shared server environment this can be used as a denial-of-service
> against a specific session. Combined with
> connection pooling or persistent connections it could repeatedly crash
> backend processes.
>
> PREREQUISITES
> ===============
> 1. Any connected database user
> 2. EXECUTE on dblink_get_notify (granted to PUBLIC by default)
> 3. contrib/dblink installed (CREATE EXTENSION dblink)
>
> No dblink connection needed. No password needed.
>
> STEPS TO REPRODUCE
> ====================
> -- STEP 1: Install dblink
> CREATE EXTENSION dblink;
>
> -- STEP 2: As any user, call without connecting first
> SELECT * FROM dblink_get_notify();
>
> -- Result before fix:
> -- server closed the connection unexpectedly
> -- SIGSEGV in server log
>
> -- Result after fix:
> -- ERROR: connection not available
>
> THE FIX
> =======
> Add the same NULL guard that every other dblink function already has:
>
> /* BEFORE */
> else
> conn = pconn->conn;
>
> /* AFTER */
> else
> {
> conn = pconn->conn;
> if (!conn)
> dblink_conn_not_avail(NULL);
> }
>
> 4 lines added. Patch attached.
>
> BEHAVIOUR AFTER THE FIX
> ========================
> -- No prior connection:
> SELECT * FROM dblink_get_notify();
> -- ERROR: connection not available (clean error, no crash)
>
> -- With valid connection:
> SELECT * FROM dblink_get_notify('myconn');
> -- (0 rows) (works exactly as before)
>
> REGRESSION TEST RESULTS
> =========================
> $ meson test --suite dblink
> 1/2 dblink - postgresql:dblink/regress OK (all SQL tests pass)
> 2/2 dblink - postgresql:dblink/001_auth_scram OK 12 subtests passed
> Ok: 2 Fail: 0
>
> $ meson test --suite regress
> 1/1 regress - postgresql:regress/regress OK 245 subtests passed
> Ok: 1 Fail: 0
>
> Tested on: PostgreSQL master 0392fb900eb, Ubuntu 24.04, x86_64.
>
>
>

Attachment Content-Type Size
v1-fix-dblink-get-notify-null-crash.patch application/octet-stream 1.9 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2026-06-05 01:49:46 BUG #19512: PG 17.10: SIGSEGV in build_minmax_path (planner) and hash_bytes (HashAgg executor)
Previous Message PG Bug reporting form 2026-06-05 01:15:40 BUG #19511: contrib/dblink: NULL dereference in dblink_get_notify() when called without a prior connection