]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Avoid leaking system path from pg_available_extensions
authorAndrew Dunstan <andrew@dunslane.net>
Wed, 20 May 2026 00:49:15 +0000 (08:49 +0800)
committerAndrew Dunstan <andrew@dunslane.net>
Sat, 30 May 2026 01:51:00 +0000 (21:51 -0400)
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

src/backend/commands/extension.c
src/test/modules/test_extensions/t/001_extension_control_path.pl

index a330b5fd6cec561cf90eaa482eda10bcf4a64000..d073585c42175b32a35a2585f783114ead750318 100644 (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
 }
 
 /*
index c1cec0dc622fdfaaf8f613d1023350f37e4714e8..4a013a7da4b13b0aec35b5a9e013b7db3a3383eb 100644 (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