public inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
From: Chao Li <li.evan.chao@gmail.com>
To: PostgreSQL-development <pgsql-hackers@postgresql.org>
Cc: Andrew Dunstan <andrew@dunslane.net>
Cc: Matheus Alcantara <matheusssilv97@gmail.com>
Subject: Re: Avoid leaking system path from pg_available_extensions
Date: Wed, 20 May 2026 09:07:49 +0800
Message-ID: <07A40FBE-F3F8-4D3F-95CA-F82CECF94EEB@gmail.com> (raw)
In-Reply-To: <357C774A-ECE9-4455-B641-315205D4D9A1@gmail.com>
References: <357C774A-ECE9-4455-B641-315205D4D9A1@gmail.com>



> On May 20, 2026, at 09:00, Chao Li <li.evan.chao@gmail.com> wrote:
> 
> Hi,
> 
> I just tested “Add paths of extensions to pg_available_extensions”, and found an issue.
> 
> This is a simple repro:
> ```
> evantest=# reset extension_control_path;
> RESET
> evantest=# select * from pg_available_extensions where name = 'plpgsql';
>  name   | default_version | installed_version | location |           comment
> ---------+-----------------+-------------------+----------+------------------------------
> plpgsql | 1.0             | 1.0               | $system  | PL/pgSQL procedural language
> (1 row)
> 
> evantest=# set extension_control_path='';
> SET
> evantest=# select * from pg_available_extensions where name = 'plpgsql';
>  name   | default_version | installed_version |             location             |           comment
> ---------+-----------------+-------------------+----------------------------------+------------------------------
> plpgsql | 1.0             | 1.0               | /usr/local/pgsql/share/extension | PL/pgSQL procedural language
> (1 row)
> ```
> 
> When extension_control_path is not set, location shows “$system", which is consistent with what the documentation says:
> ```
>       <para>
>        The default value for this parameter is
>        <literal>'$system'</literal>. If the value is set to an empty
>        string, the default <literal>'$system'</literal> is also assumed.
>       </para>
> ```
> 
> However, as shown above, when I set extension_control_path to an empty string, the absolute system path is displayed. I consider this an information leakage bug.
> 
> The fix is straightforward; see the attached patch for details. After the fix, when extension_control_path is an empty string, location shows “$system” now:
> ```
> evantest=# set extension_control_path='';
> SET
> evantest=# select * from pg_available_extensions where name = 'plpgsql';
>  name   | default_version | installed_version | location |           comment
> ---------+-----------------+-------------------+----------+------------------------------
> plpgsql | 1.0             | 1.0               | $system  | PL/pgSQL procedural language
> (1 row)
> ```
> 
> Best regards,
> --
> Chao Li (Evan)
> HighGo Software Co., Ltd.
> https://www.highgo.com/
> 
> 
> 
> 

Oops, forgot the attachment. Here comes it.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v1-0001-Avoid-leaking-system-path-from-pg_available_exten.patch (2.6K, 2-v1-0001-Avoid-leaking-system-path-from-pg_available_exten.patch)
  download | inline diff:
From 0f9398b34a5484edbb93cb7771d6204bb37b6f7c Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Wed, 20 May 2026 08:49:15 +0800
Subject: [PATCH v1] Avoid leaking system path from pg_available_extensions

The documentation says that when extension_control_path is set to an
empty string, the default '$system' path is still assumed.  However,
get_extension_control_directories() added the system extension directory
with a NULL macro in that case.  As a result, pg_available_extensions
could expose the expanded system directory path instead of reporting
'$system' as the location.

Record the implicitly-added system directory with the '$system' macro, so
pg_available_extensions reports the documented symbolic location and does
not leak the actual system path.

Update the extension_control_path TAP test to check the reported location
directly.

Author: Chao Li <lic@highgo.com>
Reviewed-by:
Discussion: https://postgr.es/m/
---
 src/backend/commands/extension.c                            | 2 +-
 .../modules/test_extensions/t/001_extension_control_path.pl | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index a330b5fd6ce..98f9d7018ae 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -526,7 +526,7 @@ get_extension_control_directories(void)
 	{
 		ExtensionLocation *location = palloc_object(ExtensionLocation);
 
-		location->macro = NULL;
+		location->macro = pstrdup("$system");
 		location->loc = system_dir;
 		paths = lappend(paths, location);
 	}
diff --git a/src/test/modules/test_extensions/t/001_extension_control_path.pl b/src/test/modules/test_extensions/t/001_extension_control_path.pl
index c1cec0dc622..4a013a7da4b 100644
--- a/src/test/modules/test_extensions/t/001_extension_control_path.pl
+++ b/src/test/modules/test_extensions/t/001_extension_control_path.pl
@@ -109,10 +109,10 @@ is($ret, "t",
 	"\$system extension is shown correctly in pg_available_extensions");
 
 $ret = $node->safe_psql('postgres',
-	"set extension_control_path = ''; select count(*) > 0 as ok from pg_available_extensions where name = 'plpgsql'"
+	"set extension_control_path = ''; select location from pg_available_extensions where name = 'plpgsql'"
 );
-is($ret, "t",
-	"\$system extension is shown correctly in pg_available_extensions with empty extension_control_path"
+is($ret, "\$system",
+	"\$system location is shown correctly in pg_available_extensions with empty extension_control_path"
 );
 
 # Test with an extension that does not exists
-- 
2.50.1 (Apple Git-155)



reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: li.evan.chao@gmail.com, andrew@dunslane.net, matheusssilv97@gmail.com
  Subject: Re: Avoid leaking system path from pg_available_extensions
  In-Reply-To: <07A40FBE-F3F8-4D3F-95CA-F82CECF94EEB@gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox