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: Lu Feng <fnlo1995@gmail.com>
Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com>
Reviewed-by: Jim Jones <jim.jones@uni-muenster.de>
Discussion: https://postgr.es/m/357C774A-ECE9-4455-B641-315205D4D9A1@gmail.com
This commit is contained in:
Andrew Dunstan 2026-05-20 08:49:15 +08:00
parent 7dc5bbcf22
commit db5ed03217
2 changed files with 8 additions and 6 deletions

View file

@ -513,6 +513,7 @@ is_extension_script_filename(const char *filename)
static List *
get_extension_control_directories(void)
{
#define EXTENSION_SYSTEM_MACRO "$system"
char sharepath[MAXPGPATH];
char *system_dir;
char *ecp;
@ -526,7 +527,7 @@ get_extension_control_directories(void)
{
ExtensionLocation *location = palloc_object(ExtensionLocation);
location->macro = NULL;
location->macro = pstrdup(EXTENSION_SYSTEM_MACRO);
location->loc = system_dir;
paths = lappend(paths, location);
}
@ -556,10 +557,10 @@ get_extension_control_directories(void)
* Substitute the path macro if needed or append "extension"
* suffix if it is a custom extension control path.
*/
if (strcmp(piece, "$system") == 0)
if (strcmp(piece, EXTENSION_SYSTEM_MACRO) == 0)
{
location->macro = pstrdup(piece);
mangled = substitute_path_macro(piece, "$system", system_dir);
mangled = substitute_path_macro(piece, EXTENSION_SYSTEM_MACRO, system_dir);
}
else
{
@ -582,6 +583,7 @@ get_extension_control_directories(void)
}
return paths;
#undef EXTENSION_SYSTEM_MACRO
}
/*

View file

@ -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