[PATCH] Allow bare library names for non-superuser LOAD

Started by cca5507about 2 months ago8 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253657
psql -h localhost -U postgres

Built from patchset v1 (message #1), October 23, 2026 at 05:38 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253657_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253657_1 && git checkout t253657_1

Patchset v1 (message #1) is on t253657_1

Jump to latest
#1cca5507
cca5507@qq.com

Hi,

Non-superusers may use LOAD only for libraries located in
$libdir/plugins, but currently they must specify that directory
explicitly, for example:

LOAD '$libdir/plugins/mylib';

This differs from local_preload_libraries, which accepts a bare library
name and automatically prepends $libdir/plugins.

The attached patch moves this expansion from load_libraries() into
load_file(). As a result, a non-superuser can write:

LOAD 'mylib';

and have it interpreted as:

LOAD '$libdir/plugins/mylib';

Thoughts?

--
Regards,
ChangAo Chen

Attachments:

t253657_1
v1-0001-Allow-bare-library-names-for-non-superuser-LOAD.patchapplication/octet-stream; charset=utf-8; name=v1-0001-Allow-bare-library-names-for-non-superuser-LOAD.patchDownload+19-16
#2Japin Li
japinli@hotmail.com
In reply to: cca5507 (#1)
Re: [PATCH] Allow bare library names for non-superuser LOAD

On Thu, 03 Sep 2026 at 20:11, "cca5507" <cca5507@qq.com> wrote:

Hi,

Non-superusers may use LOAD only for libraries located in
$libdir/plugins, but currently they must specify that directory
explicitly, for example:

LOAD '$libdir/plugins/mylib';

According to the documentation [1]https://www.postgresql.org/docs/current/sql-load.html, this is expected behavior.

Non-superusers can only apply LOAD to library files located in $libdir/plugins/ —
the specified filename must begin with exactly that string.

This differs from local_preload_libraries, which accepts a bare library
name and automatically prepends $libdir/plugins.

The attached patch moves this expansion from load_libraries() into
load_file(). As a result, a non-superuser can write:

LOAD 'mylib';

and have it interpreted as:

LOAD '$libdir/plugins/mylib';

Thoughts?

--
Regards,
ChangAo Chen

[1]: https://www.postgresql.org/docs/current/sql-load.html

--
Regards,
Japin Li
ChengDu WenWu Information Technology Co., Ltd.

#3cca5507
cca5507@qq.com
In reply to: Japin Li (#2)
Re: [PATCH] Allow bare library names for non-superuser LOAD

According to the documentation [1], this is expected behavior.

Non-superusers can only apply LOAD to library files located in $libdir/plugins/ —
        the specified filename must begin with exactly that string. 

Yes, I knew that this is the expected behavior, but it's not very convenient for
non-superusers, right? Therefore, I would like to propose a patch that allows
non-superusers to omit the $libdir/plugins/ prefix and let postgres to expand
it automatically.

--
Regards,
ChangAo Chen

#4Japin Li
japinli@hotmail.com
In reply to: cca5507 (#3)
Re: [PATCH] Allow bare library names for non-superuser LOAD

On Thu, 03 Sep 2026 at 21:17, "cca5507" <cca5507@qq.com> wrote:

According to the documentation [1], this is expected behavior.

Non-superusers can only apply LOAD to library files located in $libdir/plugins/ —
        the specified filename must begin with exactly that string. 

Yes, I knew that this is the expected behavior, but it's not very convenient for
non-superusers, right?

Yeah, it's a bit inconvenient.

Therefore, I would like to propose a patch that allows
non-superusers to omit the $libdir/plugins/ prefix and let postgres to expand
it automatically.

The $libdir/plugins directory was introduced in commit abc3120e9b2. It
automatically expands for local_shared_libraries, but not for LOAD command.
I'm not sure if that was intentional.

Other than that, it looks good.

--
Regards,
ChangAo Chen

--
Regards,
Japin Li
ChengDu WenWu Information Technology Co., Ltd.

#5solai v
solai.cdac@gmail.com
In reply to: Japin Li (#2)
Re: [PATCH] Allow bare library names for non-superuser LOAD

Hi all
I reviewed and tested the v1 patch for allowing bare library names for
non-superuser LOAD.
I was able to reproduce the existing behavior before applying the patch:
-As a non-superuser, LOAD mylib failed with access to library mylib is
not allowed.
-LOAD $libdir/plugins/mylib succeeded.

After applying the v1 patch and rebuilding/restarting PostgreSQL:
-LOAD mylib succeeded and loaded the library from $libdir/plugins.
-LOAD $libdir/plugins/mylib continued to work.
-Attempts to load /tmp/mylib.so, $libdir/mylib, and ../mylib were
still rejected for the non-superuser.
I also ran git diff --check, which completed without any errors.

From my testing, the patch fixes the reported issue while preserving
the existing security restriction for non-superuser LOAD.
I did not find any functional issue with the patch during these tests.

Regards
solai

#6Jim Jones
jim.jones@uni-muenster.de
In reply to: solai v (#5)
Re: [PATCH] Allow bare library names for non-superuser LOAD

Hi,
Thanks for the patch.

I have two quick observations:

== LOAD semantics ==

LOAD now means different things depending on which user runs it, which
can be quite problematic for scripting. For instance in the following
scenario, where we have two modules with the same name living in
different directories:

$ LIBDIR=$(pg_config --pkglibdir)
$ cp $LIBDIR/passwordcheck.so $LIBDIR/demo.so
$ cp $LIBDIR/auto_explain.so $LIBDIR/plugins/demo.so

-- a superuser loads the lib from the root directory:
postgres=# LOAD 'demo';
LOAD
postgres=# SELECT count(*) FROM pg_settings WHERE name LIKE 'auto_explain%';
count
-------
0
(1 row)

-- a normal user loads it from the plugins directory, although the
command is identical

postgres=# CREATE USER foo;
CREATE ROLE
postgres=# SET ROLE foo;
SET
postgres=> LOAD 'demo';
LOAD
postgres=> SELECT count(*) FROM pg_settings WHERE name LIKE 'auto_explain%';
count
-------
15
(1 row)

Without the patch we get an ERROR, which is arguably better than "the
wrong file":

postgres=> LOAD 'demo';
ERROR: access to library "demo" is not allowed

== error message ==

The error message now says something else (different sqlstates?):

postgres=> LOAD 'pg_stat_statements';
ERROR: could not access file "$libdir/plugins/pg_stat_statements": No
such file or directory

Without the patch:

postgres=> LOAD 'pg_stat_statements';
ERROR: access to library "pg_stat_statements" is not allowed

I believe that this kind of error reclassification might confuse
monitoring tools -- IMO not a blocker, but must be well justified.

Best, Jim

#7cca5507
cca5507@qq.com
In reply to: Jim Jones (#6)
Re: [PATCH] Allow bare library names for non-superuser LOAD

I have two quick observations:

== LOAD semantics ==

LOAD now means different things depending on which user runs it, which
can be quite problematic for scripting. For instance in the following
scenario, where we have two modules with the same name living in
different directories:

$ LIBDIR=$(pg_config --pkglibdir)
$ cp $LIBDIR/passwordcheck.so $LIBDIR/demo.so
$ cp $LIBDIR/auto_explain.so  $LIBDIR/plugins/demo.so

I think we just need to avoid doing something like this: different libraries
with the same name.

== error message ==

The error message now says something else (different sqlstates?):

postgres=> LOAD 'pg_stat_statements';
ERROR:  could not access file "$libdir/plugins/pg_stat_statements": No
such file or directory

Without the patch:

postgres=> LOAD 'pg_stat_statements';
ERROR:  access to library "pg_stat_statements" is not allowed

I believe that this kind of error reclassification might confuse
monitoring tools -- IMO not a blocker, but must be well justified.

The behavior of "local_preload_libraries" also like this. So I think it's
ok if we document the auto expand of "$libdir/plugins/" clearly.

--
Regards,
ChangAo Chen

#8Jim Jones
jim.jones@uni-muenster.de
In reply to: cca5507 (#7)
Re: [PATCH] Allow bare library names for non-superuser LOAD

On 09/09/2026 10:04, cca5507 wrote:

I think we just need to avoid doing something like this: different libraries
with the same name.

As a general rule I totally agree with you. I just wonder if it should
be possible in the first place. My point is that we could be trading
server guarantee for admin discipline.

The behavior of "local_preload_libraries" also like this. So I think it's
ok if we document the auto expand of "$libdir/plugins/" clearly.

Fair enough.

Thanks!

Best, Jim