Thread
Commits
-
pg_buffercache: restore rowtype verification in pg_buffercache_pages()
- b70d5672d0c5 19 (unreleased) landed
-
Modernize and optimize pg_buffercache_pages()
- 257c8231bf97 19 (unreleased) cited
-
BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
The Post Office <noreply@postgresql.org> — 2026-06-04T14:35:10Z
The following bug has been logged on the website: Bug reference: 19508 Logged by: Nikita Kalinin Email address: n.kalinin@postgrespro.ru PostgreSQL version: 19beta1 Operating system: Fedora 44 Description: Hello, It appears that pg_buffercache_pages() trusts a caller-supplied record descriptor without verifying that the declared column types match the actual values returned by the function. The crash is reproducible on the current master branch with a fresh cluster after installing the extension: CREATE EXTENSION pg_buffercache; SELECT * FROM pg_buffercache_pages() AS p( bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid, relforknumber smallint, relblocknumber bigint, isdirty text, usagecount smallint ) LIMIT 1; postgres=# select version(); version ------------------------------------------------------------------------------------------------------------- PostgreSQL 19beta1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 16.1.1 20260515 (Red Hat 16.1.1-2), 64-bit (1 row) The only difference from the types documented for pg_buffercache_pages() is that isdirty is declared as text instead of boolean. git blame points to the following commit: commit 257c8231bf97a77378f6fedb826b1243f0a41612 (HEAD) Author: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Tue Apr 7 16:04:48 2026 +0300 Modernize and optimize pg_buffercache_pages() Backtrace: #0 0x00000000004b2565 in VARATT_CAN_MAKE_SHORT (PTR=<optimized out>) at ../../../../src/include/varatt.h:419 #1 heap_compute_data_size (tupleDesc=tupleDesc@entry=0x3e5ba110, values=values@entry=0x7ffd0dc219c0, isnull=isnull@entry=0x7ffd0dc219b4) at heaptuple.c:239 #2 0x00000000004b3bff in heap_form_minimal_tuple (tupleDescriptor=0x3e5ba110, values=values@entry=0x7ffd0dc219c0, isnull=isnull@entry=0x7ffd0dc219b4, extra=extra@entry=0) at heaptuple.c:1434 #3 0x0000000000a6fa09 in tuplestore_putvalues (state=0x3e5cc0d8, tdesc=<optimized out>, values=values@entry=0x7ffd0dc219c0, isnull=isnull@entry=0x7ffd0dc219b4) at tuplestore.c:791 #4 0x00007f180fa0447e in pg_buffercache_pages (fcinfo=<optimized out>) at pg_buffercache_pages.c:202 #5 0x00000000006b7e35 in ExecMakeTableFunctionResult (setexpr=0x3e5b9e98, econtext=0x3e5b9d38, argContext=<optimized out>, expectedDesc=0x3e5ba110, randomAccess=false) at execSRF.c:235 #6 0x00000000006ccc57 in FunctionNext (node=0x3e5b9b28) at nodeFunctionscan.c:95 #7 0x00000000006daf22 in ExecProcNode (node=0x3e5b9b28) at ../../../src/include/executor/executor.h:327 #8 ExecLimit (pstate=0x3e5b97b8) at nodeLimit.c:95 #9 0x00000000006ac39a in ExecProcNode (node=0x3e5b97b8) at ../../../src/include/executor/executor.h:327 #10 ExecutePlan (queryDesc=0x3e5d7d80, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=<optimized out>, dest=0x3e5e11f8) at execMain.c:1736 #11 standard_ExecutorRun (queryDesc=0x3e5d7d80, direction=<optimized out>, count=0) at execMain.c:377 #12 0x00000000008c61d8 in PortalRunSelect (portal=portal@entry=0x3e52f130, forward=forward@entry=true, count=0, count@entry=9223372036854775807, dest=dest@entry=0x3e5e11f8) at pquery.c:917 #13 0x00000000008c78be in PortalRun (portal=portal@entry=0x3e52f130, count=count@entry=9223372036854775807, isTopLevel=isTopLevel@entry=true, dest=dest@entry=0x3e5e11f8, altdest=altdest@entry=0x3e5e11f8, qc=qc@entry=0x7ffd0dc21e20) at pquery.c:761 #14 0x00000000008c3548 in exec_simple_query ( query_string=0x3e48b800 "SELECT *\nFROM pg_buffercache_pages() AS p(\n bufferid integer,\n relfilenode oid,\n reltablespace oid,\n reldatabase oid,\n relforknumber smallint,\n relblocknumber bigint,\n isdirty text,\n usagecoun"...) at postgres.c:1290 #15 0x00000000008c5021 in PostgresMain (dbname=<optimized out>, username=<optimized out>) at postgres.c:4856 #16 0x00000000008bf01d in BackendMain (startup_data=<optimized out>, startup_data_len=<optimized out>) at backend_startup.c:124 #17 0x00000000007fefae in postmaster_child_launch (child_type=<optimized out>, child_slot=1, startup_data=startup_data@entry=0x7ffd0dc22270, startup_data_len=startup_data_len@entry=24, client_sock=client_sock@entry=0x7ffd0dc22290) at launch_backend.c:268 #18 0x00000000008029b6 in BackendStartup (client_sock=0x7ffd0dc22290) at postmaster.c:3627 #19 ServerLoop () at postmaster.c:1728 #20 0x0000000000804479 in PostmasterMain (argc=argc@entry=3, argv=argv@entry=0x3e434fe0) at postmaster.c:1415 #21 0x00000000004a1c18 in main (argc=3, argv=0x3e434fe0) at main.c:231 For comparison, the same query executed on REL_18_STABLE is rejected with a regular error: ERROR: function return row and query-specified return row do not match DETAIL: Returned type boolean at ordinal position 7, but query expects text. -
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Fujii Masao <masao.fujii@gmail.com> — 2026-06-05T03:18:49Z
On Fri, Jun 5, 2026 at 12:49 AM PG Bug reporting form <noreply@postgresql.org> wrote: > > The following bug has been logged on the website: > > Bug reference: 19508 > Logged by: Nikita Kalinin > Email address: n.kalinin@postgrespro.ru > PostgreSQL version: 19beta1 > Operating system: Fedora 44 > Description: > > Hello, > > It appears that pg_buffercache_pages() trusts a caller-supplied record > descriptor without verifying that the declared column types match the actual > values returned by the function. > > The crash is reproducible on the current master branch with a fresh cluster > after installing the extension: Thanks for the report! I could reproduce this as well. > git blame points to the following commit: > > commit 257c8231bf97a77378f6fedb826b1243f0a41612 (HEAD) > Author: Heikki Linnakangas <heikki.linnakangas@iki.fi> > Date: Tue Apr 7 16:04:48 2026 +0300 > > Modernize and optimize pg_buffercache_pages() Commit 257c8231bf9 changed pg_buffercache_pages() to materialize rows directly into a tuplestore. As a result, the function started using the caller-supplied RECORD descriptor as rsinfo->setDesc, so a mismatched column definition list could cause tuplestore_putvalues() to interpret returned Datums with incorrect types. Before that change, pg_buffercache_pages() exposed its actual tuple descriptor to the executor, allowing the executor's existing rowtype checks to reject incompatible definitions with a normal error. The attached patch restores that behavior while keeping the materialized-SRF implementation. Thoughts? Regards, -- Fujii Masao
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-06-05T03:42:20Z
Hi, On Fri, 5 Jun 2026 at 08:49, Fujii Masao <masao.fujii@gmail.com> wrote: > > Commit 257c8231bf9 changed pg_buffercache_pages() to materialize rows > directly > into a tuplestore. As a result, the function started using the > caller-supplied > RECORD descriptor as rsinfo->setDesc, so a mismatched column definition > list > could cause tuplestore_putvalues() to interpret returned Datums with > incorrect > types. > > Before that change, pg_buffercache_pages() exposed its actual tuple > descriptor > to the executor, allowing the executor's existing rowtype checks to reject > incompatible definitions with a normal error. > > The attached patch restores that behavior while keeping the > materialized-SRF > implementation. Thoughts? > Thanks for the patch, Fujii-san! I was looking into the bug last night, and the approach looks right to me. This still means InitMaterializedSRF() briefly creates the caller-derived descriptor before rsinfo->setDesc is replaced. That seems acceptable here: the descriptor lives only in the per-query context, and avoiding a local copy of InitMaterializedSRF() keeps the fix much smaller and less fragile. One small nit: build_buffercache_pages_tupledesc() names attribute 8 "usage_count", while the existing pg_buffercache view and the test use "usagecount". This probably does not affect the tupledesc_match() check, but I think it would be better to keep the existing spelling for consistency. Regards, Ayush
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Fujii Masao <masao.fujii@gmail.com> — 2026-06-05T07:58:07Z
On Fri, Jun 5, 2026 at 12:42 PM Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote: > One small nit: build_buffercache_pages_tupledesc() names attribute 8 > "usage_count", while the existing pg_buffercache view and the test use > "usagecount". This probably does not affect the tupledesc_match() check, > but I think it would be better to keep the existing spelling for > consistency. Agreed. I've fixed that and attached an updated version of the patch. Regards, -- Fujii Masao
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-06-05T08:47:58Z
Hi, On Fri, 5 Jun, 2026, 13:28 Fujii Masao, <masao.fujii@gmail.com> wrote: > On Fri, Jun 5, 2026 at 12:42 PM Ayush Tiwari > <ayushtiwari.slg01@gmail.com> wrote: > > One small nit: build_buffercache_pages_tupledesc() names attribute 8 > > "usage_count", while the existing pg_buffercache view and the test use > > "usagecount". This probably does not affect the tupledesc_match() check, > > but I think it would be better to keep the existing spelling for > > consistency. > > Agreed. I've fixed that and attached an updated version of the patch. > LGTM. Regards, Ayush >
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Ashutosh Sharma <ashu.coek88@gmail.com> — 2026-06-05T15:29:23Z
Hi Fujii-san, On Fri, Jun 5, 2026 at 8:49 AM Fujii Masao <masao.fujii@gmail.com> wrote: > > On Fri, Jun 5, 2026 at 12:49 AM PG Bug reporting form > <noreply@postgresql.org> wrote: > > > > The following bug has been logged on the website: > > > > Bug reference: 19508 > > Logged by: Nikita Kalinin > > Email address: n.kalinin@postgrespro.ru > > PostgreSQL version: 19beta1 > > Operating system: Fedora 44 > > Description: > > > > Hello, > > > > It appears that pg_buffercache_pages() trusts a caller-supplied record > > descriptor without verifying that the declared column types match the actual > > values returned by the function. > > > > The crash is reproducible on the current master branch with a fresh cluster > > after installing the extension: > > Thanks for the report! I could reproduce this as well. > > > > git blame points to the following commit: > > > > commit 257c8231bf97a77378f6fedb826b1243f0a41612 (HEAD) > > Author: Heikki Linnakangas <heikki.linnakangas@iki.fi> > > Date: Tue Apr 7 16:04:48 2026 +0300 > > > > Modernize and optimize pg_buffercache_pages() > > Commit 257c8231bf9 changed pg_buffercache_pages() to materialize rows directly > into a tuplestore. As a result, the function started using the caller-supplied > RECORD descriptor as rsinfo->setDesc, so a mismatched column definition list > could cause tuplestore_putvalues() to interpret returned Datums with incorrect > types. > > Before that change, pg_buffercache_pages() exposed its actual tuple descriptor > to the executor, allowing the executor's existing rowtype checks to reject > incompatible definitions with a normal error. > > The attached patch restores that behavior while keeping the materialized-SRF > implementation. Thoughts? > pg_buffercache_pages uses RETURNS SETOF RECORD whereas other extensions like pgstattuple define explicit IN/OUT parameters at the SQL level. Is there a specific reason this pattern was kept, or is it simply a legacy design that hasn't been modernized? Had we followed the IN/OUT parameter style, this sort of issue could have been avoided, no? -- With Regards, Ashutosh Sharma.
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Fujii Masao <masao.fujii@gmail.com> — 2026-06-05T15:38:15Z
On Sat, Jun 6, 2026 at 12:29 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote: > pg_buffercache_pages uses RETURNS SETOF RECORD whereas other > extensions like pgstattuple define explicit IN/OUT parameters at the > SQL level. Is there a specific reason this pattern was kept, or is it > simply a legacy design that hasn't been modernized? Had we followed > the IN/OUT parameter style, this sort of issue could have been > avoided, no? Probably yes. But if we do that, we would likely need to bump pg_buffercache version. I'm not sure that's worthwhile just for this change. Regards, -- Fujii Masao
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Fujii Masao <masao.fujii@gmail.com> — 2026-06-08T23:44:50Z
On Fri, Jun 5, 2026 at 5:48 PM Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote: >> Agreed. I've fixed that and attached an updated version of the patch. > > > LGTM. Barring any objections, I will commit the patch. Regards, -- Fujii Masao
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Ashutosh Sharma <ashu.coek88@gmail.com> — 2026-06-09T04:38:58Z
On Fri, Jun 5, 2026 at 9:08 PM Fujii Masao <masao.fujii@gmail.com> wrote: > > On Sat, Jun 6, 2026 at 12:29 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote: > > pg_buffercache_pages uses RETURNS SETOF RECORD whereas other > > extensions like pgstattuple define explicit IN/OUT parameters at the > > SQL level. Is there a specific reason this pattern was kept, or is it > > simply a legacy design that hasn't been modernized? Had we followed > > the IN/OUT parameter style, this sort of issue could have been > > avoided, no? > > Probably yes. But if we do that, we would likely need to bump pg_buffercache > version. I'm not sure that's worthwhile just for this change. > Okay, that makes perfect sense, thanks for the confirmation. -- With Regards, Ashutosh Sharma.
-
Re: BUG #19508: pg_buffercache_pages() crashes the backend with an incompatible caller-supplied record definition
Fujii Masao <masao.fujii@gmail.com> — 2026-06-10T03:34:34Z
On Tue, Jun 9, 2026 at 8:44 AM Fujii Masao <masao.fujii@gmail.com> wrote: > > On Fri, Jun 5, 2026 at 5:48 PM Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote: > >> Agreed. I've fixed that and attached an updated version of the patch. > > > > > > LGTM. > > Barring any objections, I will commit the patch. I've pushed the patch. Thanks! Regards, -- Fujii Masao