public inbox for [email protected]
help / color / mirror / Atom feedBUG #19523: psql tab-completion shadows pg_db_role_setting
2+ messages / 2 participants
[nested] [flat]
* BUG #19523: psql tab-completion shadows pg_db_role_setting
@ 2026-06-18 07:06 PG Bug reporting form <[email protected]>
0 siblings, 1 reply; 2+ messages in thread
From: PG Bug reporting form @ 2026-06-18 07:06 UTC (permalink / raw)
To: [email protected]; +Cc: [email protected]
The following bug has been logged on the website:
Bug reference: 19523
Logged by: Zhou Digoal
Email address: [email protected]
PostgreSQL version: 19beta1
Operating system: macOS
Description:
# 🐛 [BUG] psql tab-completion shadows pg_db_role_setting
## Environment
| Item | Value |
| --- | --- |
| OS | macOS 15.7.7 (build 24G720) |
| Kernel | Darwin 24.6.0 |
| Compiler | Apple clang version 17.0.0 (clang-1700.6.4.2) |
| PG version | 19beta1 (`pg_config --version`) |
| Source branch | `master` |
| Source commit | `850b9218c8e4aa7a56f4ec34a542d4a37f9e07eb` |
| `git describe` | `850b921` |
| Build flags | `--enable-debug --enable-cassert --enable-debug-symbols` |
| Configure | `$PGBIN/pg_config --configure` |
---
## Summary
The query that psql tab-completion runs to list database-scoped GUC names
(Query_for_list_of_database_vars in src/bin/psql/tab-complete.c, duplicated
in src/bin/psql/tab-complete.in.c) references the system catalog table
pg_db_role_setting without the pg_catalog. schema qualifier. A user with
CREATE privilege on any schema earlier in search_path than pg_catalog can
therefore shadow the catalog table and influence tab-completion suggestions
for ALTER DATABASE SET.
---
## Commit under test
`850b9218c8e4aa7a56f4ec34a542d4a37f9e07eb` on branch `master`. The full
source HEAD at report
time is `850b9218c8e4aa7a56f4ec34a542d4a37f9e07eb` (`git describe` →
`850b921`).
---
## Reproduction
Repro file: `/tmp/repro_pg_db_role_setting.sql`
```sql
CREATE SCHEMA attacker;
CREATE TABLE attacker.pg_db_role_setting (
setdatabase oid,
setrole oid,
setconfig text[]
);
INSERT INTO attacker.pg_db_role_setting
SELECT oid, 0, ARRAY['custom_var=value', 'session_replication_role=replica']
FROM pg_database WHERE datname = 'postgres';
SET search_path = attacker, pg_catalog;
SELECT conf FROM (
SELECT setdatabase,
pg_catalog.split_part(pg_catalog.unnest(setconfig),'=',1) conf
FROM pg_db_role_setting
) s, pg_database d
WHERE s.setdatabase = d.oid
AND conf LIKE 'c%'
AND d.datname LIKE 'p%';
RESET search_path;
DROP SCHEMA attacker CASCADE;
```
### Actual output
```
Returned one row 'custom_var' that was read from attacker.pg_db_role_setting
rather than from the system catalog (which is empty for this database).
```
### Server log (last lines)
```
CREATE SCHEMA attacker;
CREATE SCHEMA
CREATE TABLE attacker.pg_db_role_setting (
setdatabase oid,
setrole oid,
setconfig text[]
);
CREATE TABLE
INSERT INTO attacker.pg_db_role_setting
SELECT oid, 0, ARRAY['custom_var=value', 'session_replication_role=replica']
FROM pg_database WHERE datname = 'postgres';
INSERT 0 1
SET search_path = attacker, pg_catalog;
SET
SELECT conf FROM (
SELECT setdatabase,
pg_catalog.split_part(pg_catalog.unnest(setconfig),'=',1) conf
FROM pg_db_role_setting
) s, pg_database d
WHERE s.setdatabase = d.oid
AND conf LIKE 'c%'
AND d.datname LIKE 'p%';
conf
------------
custom_var
(1 row)
RESET search_path;
RESET
DROP SCHEMA attacker CASCADE;
psql:/tmp/repro_pg_db_role_setting.sql:48: NOTICE: drop cascades to table
attacker.pg_db_role_setting
DROP SCHEMA
```
### Expected output
```
Zero rows; the query should resolve pg_db_role_setting to the system catalog
table regardless of search_path.
```
---
## Why is this a bug?
Commit bf5206f (psql: Add some missing schema qualifications in describe.c)
fixed the same class of bug for describe.c but missed tab-complete.c and
tab-complete.in.c. A user who can create a table named pg_db_role_setting in
a schema that appears before pg_catalog in search_path can have psql issue
its tab-completion query against the shadow table instead of the real
catalog, returning attacker- controlled GUC names. This violates the
documented psql behavior of suggesting actual database-level GUC settings.
---
## Suggested fix
Qualify the reference in src/bin/psql/tab-complete.in.c (line 1043) and the
generated src/bin/psql/tab-complete.c (line 1064) by changing FROM
pg_db_role_setting to FROM pg_catalog.pg_db_role_setting, then regenerate
tab-complete.c on rebuild.
---
## Severity
**medium** — see Environment block.
^ permalink raw reply [nested|flat] 2+ messages in thread
* [PATCH v1] psql: schema-qualify catalog references in a tab-completion query
@ 2026-07-09 12:23 Vismay Tiwari <[email protected]>
parent: PG Bug reporting form <[email protected]>
0 siblings, 0 replies; 2+ messages in thread
From: Vismay Tiwari @ 2026-07-09 12:23 UTC (permalink / raw)
To: [email protected]
The tab-completion query behind Query_for_list_of_database_vars referenced
pg_db_role_setting and pg_database without schema qualification. A table of
the same name earlier in the user's search_path therefore shadows the catalog
and feeds arbitrary values into the completion suggestions for
"ALTER DATABASE ... RESET". Qualify both with pg_catalog, matching the
qualification already applied to unnest()/split_part() in this same query and
to the catalogs in the analogous subscription-variable completion query.
Reported-by: Zhou Digoal
Bug: #19523
Discussion: https://postgr.es/m/[email protected]
---
Resending in-thread: my earlier copy of this patch reached the list without an
In-Reply-To header, so it landed unthreaded rather than under the report.
Same patch, no changes.
src/bin/psql/tab-complete.in.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 49ea584..6a88470 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -1040,8 +1040,8 @@ static const SchemaQuery Query_for_trigger_of_table = {
#define Query_for_list_of_database_vars \
"SELECT conf FROM ("\
" SELECT setdatabase, pg_catalog.split_part(pg_catalog.unnest(setconfig),'=',1) conf"\
-" FROM pg_db_role_setting "\
-" ) s, pg_database d "\
+" FROM pg_catalog.pg_db_role_setting "\
+" ) s, pg_catalog.pg_database d "\
" WHERE s.setdatabase = d.oid "\
" AND conf LIKE '%s'"\
" AND d.datname LIKE '%s'"
--
2.50.1 (Apple Git-155)
^ permalink raw reply [nested|flat] 2+ messages in thread
end of thread, other threads:[~2026-07-09 12:23 UTC | newest]
Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-06-18 07:06 BUG #19523: psql tab-completion shadows pg_db_role_setting PG Bug reporting form <[email protected]>
2026-07-09 12:23 ` [PATCH v1] psql: schema-qualify catalog references in a tab-completion query Vismay Tiwari <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox