From f0726593e983a3d31d74859a4a78e8c31b3a037e Mon Sep 17 00:00:00 2001 From: ChangAo Chen Date: Thu, 3 Sep 2026 19:58:04 +0800 Subject: [PATCH v1] Allow bare library names for non-superuser LOAD Non-superusers can use LOAD only for libraries in $libdir/plugins, but they currently have to specify that directory explicitly. This differs from local_preload_libraries, which adds the directory for bare library names. Move this expansion into load_file() so all restricted loads handle bare names consistently. --- doc/src/sgml/ref/load.sgml | 10 +++++----- src/backend/utils/fmgr/dfmgr.c | 15 ++++++++++++++- src/backend/utils/init/miscinit.c | 9 --------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/ref/load.sgml b/doc/src/sgml/ref/load.sgml index 2c214dd726d..6ea2290c6ef 100644 --- a/doc/src/sgml/ref/load.sgml +++ b/doc/src/sgml/ref/load.sgml @@ -53,11 +53,11 @@ LOAD 'filename' Non-superusers can only apply LOAD to library files - located in $libdir/plugins/ — the specified - filename must begin - with exactly that string. (It is the database administrator's - responsibility to ensure that only safe libraries - are installed there.) + located in $libdir/plugins/. If the specified + filename is a bare file + name, $libdir/plugins/ is prepended automatically. + Otherwise, it must begin with exactly that string. Administrators + must ensure that only safe libraries are installed there. diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index e636cc81cf8..49bcdde9773 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -143,16 +143,27 @@ load_external_function(const char *filename, const char *funcname, * we do not load it again. * * When 'restricted' is true, only libraries in the presumed-secure - * directory $libdir/plugins may be referenced. + * directory $libdir/plugins may be referenced. A bare library name is + * automatically expanded into that directory. */ void load_file(const char *filename, bool restricted) { char *fullname; + char *expanded = NULL; /* Apply security restriction if requested */ if (restricted) + { + /* Insert $libdir/plugins if not mentioned already */ + if (first_dir_separator(filename) == NULL) + { + expanded = psprintf("$libdir/plugins/%s", filename); + filename = expanded; + } + check_restricted_library_name(filename); + } /* Expand the possibly-abbreviated filename to an exact path name */ fullname = expand_dynamic_library_name(filename); @@ -161,6 +172,8 @@ load_file(const char *filename, bool restricted) (void) internal_load_library(fullname); pfree(fullname); + if (expanded) + pfree(expanded); } /* diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index eddce1ce33f..1f7432e6d40 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -1829,19 +1829,10 @@ load_libraries(const char *libraries, const char *gucname, bool restricted) { /* Note that filename was already canonicalized */ char *filename = (char *) lfirst(l); - char *expanded = NULL; - /* If restricting, insert $libdir/plugins if not mentioned already */ - if (restricted && first_dir_separator(filename) == NULL) - { - expanded = psprintf("$libdir/plugins/%s", filename); - filename = expanded; - } load_file(filename, restricted); ereport(DEBUG1, (errmsg_internal("loaded library \"%s\"", filename))); - if (expanded) - pfree(expanded); } list_free_deep(elemlist); -- 2.53.0