From a09301fec566879beb50db044a9d51ce3b8cb6b5 Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Mon, 9 Nov 2026 16:15:01 +0800 Subject: [PATCH v2 2/3] Reject relative paths consistently in extension_control_path The available-extension views accepted relative paths, while CREATE EXTENSION rejected them only when its search reached the relative element. Move the absolute-path check into get_extension_control_directories() so all callers validate the complete search path before using it. Replace the redundant check in find_in_paths() with an assertion. Add TAP coverage for the view and CREATE EXTENSION, including a case where an earlier valid directory contains the requested extension. Reported-by: Surya Poondla Author: Chao Li Reviewed-by: Surya Poondla Discussion: https://postgr.es/m/DC2D9FA5-45C4-494F-99FC-F9B95AD4FF55@gmail.com --- src/backend/commands/extension.c | 12 +++++++----- .../t/001_extension_control_path.pl | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 058ec18908b..d1d43450f90 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -580,6 +580,12 @@ get_extension_control_directories(void) /* Canonicalize the path based on the OS and add to the list */ canonicalize_path(mangled); + if (!is_absolute_path(mangled)) + ereport(ERROR, + errcode(ERRCODE_INVALID_NAME), + errmsg("component in parameter \"%s\" is not an absolute path", + "extension_control_path")); + location->loc = mangled; paths = lappend(paths, location); @@ -4113,11 +4119,7 @@ find_in_paths(const char *basename, List *paths) path = pstrdup(path); canonicalize_path(path); - /* only absolute paths */ - if (!is_absolute_path(path)) - ereport(ERROR, - errcode(ERRCODE_INVALID_NAME), - errmsg("component in parameter \"%s\" is not an absolute path", "extension_control_path")); + Assert(is_absolute_path(path)); full = psprintf("%s/%s", path, basename); 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 76c1d4e8223..a1c87f38599 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 @@ -131,6 +131,23 @@ for my $path ( "error identifies the empty path element"); } +# Reject relative paths even if an earlier directory contains the extension. +my $relative_ext = 'test_relative_path'; +create_extension($relative_ext, $ext_dir); +for my $sql ( + 'select count(*) from pg_available_extensions', + "create extension $relative_ext") +{ + my ($code, $stdout, $stderr) = $node->psql( + 'postgres', + "set extension_control_path = '$ext_dir_canonicalized${sep}relative'; + $sql"); + is($code, 3, "relative path is rejected by $sql"); + like($stderr, + qr/ERROR: component in parameter "extension_control_path" is not an absolute path/, + "error identifies the relative path element"); +} + # Test with an extension that does not exists my ($code, $stdout, $stderr) = $node->psql('postgres', "CREATE EXTENSION invalid"); -- 2.50.1 (Apple Git-155)