glob support in extension_control_path/dynamic_library_path?

Started by Jakob Eggerabout 2 months ago11 messageshackers
Jump to latest
#1Jakob Egger
jakob@eggerapps.at

Hello!

The extension_control_path setting allowed us to offer precompiled downloadable extensions for Postgres.app: https://postgresapp.com/extensions/

We install extensions each into their own path, for example:

/Users/USER/Library/Application Support/Postgres/Extensions/18/http
/Users/USER/Library/Application Support/Postgres/Extensions/18/pg_cron
....

This allows us to update extensions by just deleting the folder and installing the new version -- we don't need to track all the files belonging to an extension. If we put all separately downloaded extensions in a single directory we would be very likely to end up with orphaned files sooner or later.

However, this leads to a rather lengthy configuration that needs to be updated whenever an extension is installed:

extension_control_path="$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_parquet/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_cron/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/http/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/timescaledb/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/plv8/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_search/share/postgresql"

It would be really nice if we could just use glob patterns like this:

extension_control_path="$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/share/postgresql"
dynamic_library_path="$libdir:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/lib/postgresql"

This would also have the advantage of not requiring a server restart after installing an extension.

I believe this would also be useful for Docker use case mentioned in the original thread (/messages/by-id/E7C7BFFB-8857-48D4-A71F-88B359FADCFD@justatheory.com) when multiple extensions are used

I have tried implementing this patch myself, and it was pretty straightforward to implement a proof of concept.

I wonder if such an addition would be useful for other packagers?

Best regards,
Jakob

#2David E. Wheeler
david@kineticode.com
In reply to: Jakob Egger (#1)
Re: glob support in extension_control_path/dynamic_library_path?

On May 29, 2026, at 14:26, Jakob Egger <jakob@eggerapps.at> wrote:

It would be really nice if we could just use glob patterns like this:

extension_control_path="$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/share/postgresql"
dynamic_library_path="$libdir:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/lib/postgresql"

This would also have the advantage of not requiring a server restart after installing an extension.

Somehow a glob never occurred to me. 🤦🏻

I believe this would also be useful for Docker use case mentioned in the original thread (/messages/by-id/E7C7BFFB-8857-48D4-A71F-88B359FADCFD@justatheory.com) when multiple extensions are used

Indeed.

I have tried implementing this patch myself, and it was pretty straightforward to implement a proof of concept.

I wonder if such an addition would be useful for other packagers?

Me too! I had been planning to propose a new directory layout, but a glob is a much simpler solution.

D

#3Matheus Alcantara
matheusssilv97@gmail.com
In reply to: Jakob Egger (#1)
Re: glob support in extension_control_path/dynamic_library_path?

On 29/05/26 09:26, Jakob Egger wrote:

Hello!

The extension_control_path setting allowed us to offer precompiled downloadable extensions for Postgres.app: https://postgresapp.com/extensions/

We install extensions each into their own path, for example:

/Users/USER/Library/Application Support/Postgres/Extensions/18/http
/Users/USER/Library/Application Support/Postgres/Extensions/18/pg_cron
....

This allows us to update extensions by just deleting the folder and installing the new version -- we don't need to track all the files belonging to an extension. If we put all separately downloaded extensions in a single directory we would be very likely to end up with orphaned files sooner or later.

However, this leads to a rather lengthy configuration that needs to be updated whenever an extension is installed:

extension_control_path="$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_parquet/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_cron/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/http/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/timescaledb/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/plv8/share/postgresql:/Users/jakob/Library/Application Support/Postgres/Extensions/18/pg_search/share/postgresql"

Yeah, I've also faced some configurations like this when working with
extension_control_path.

It would be really nice if we could just use glob patterns like this:

extension_control_path="$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/share/postgresql"
dynamic_library_path="$libdir:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/lib/postgresql"

This would also have the advantage of not requiring a server restart after installing an extension.

I believe this would also be useful for Docker use case mentioned in the original thread (/messages/by-id/E7C7BFFB-8857-48D4-A71F-88B359FADCFD@justatheory.com) when multiple extensions are used

I have tried implementing this patch myself, and it was pretty straightforward to implement a proof of concept.

I wonder if such an addition would be useful for other packagers?

Please, share the patch so we can better evaluate.

--
Matheus Alcantara
EDB: https://www.enterprisedb.com

#4Jakob Egger
jakob@eggerapps.at
In reply to: Matheus Alcantara (#3)
Re: glob support in extension_control_path/dynamic_library_path?

Am 01.06.2026 um 11:38 schrieb Matheus Alcantara <matheusssilv97@gmail.com>:

Please, share the patch so we can better evaluate.

This is my attempt at the patch. It falls back to the previous behavior on Windows (would need to use alternative to glob() syscall)

Attachments:

0001-glob-support-in-extension_search_path-and-dynamic_li.patchapplication/octet-stream; name=0001-glob-support-in-extension_search_path-and-dynamic_li.patch; x-unix-mode=0644Download+73-5
#5David E. Wheeler
david@kineticode.com
In reply to: Jakob Egger (#4)
Re: glob support in extension_control_path/dynamic_library_path?

(Added Peter Eisentraut)

On Jun 1, 2026, at 09:21, Jakob Egger <jakob@eggerapps.at> wrote:

This is my attempt at the patch. It falls back to the previous behavior on Windows (would need to use alternative to glob() syscall)

Seems simple enough. Certainly far simpler than my Packaging & Lookup RFC[0]https://justatheory.com/2024/11/rfc-extension-packaging-lookup/#solution, and solves the same problems. This would, for example, allow CNPG extension images to work as soon as they’re mounted as a directory covered by the wildcard, without requiring a Postgres restart! (k8s mounts still require a new pod, but that’s obviously not something we can change.)

[0]: https://justatheory.com/2024/11/rfc-extension-packaging-lookup/#solution

Peter E: what do you think about this as an evolution of the extension_control_path/dynamic_library_path work? Any gotchas to be aware of, aside from the current lack of Windows support?

D

#6Peter Eisentraut
peter_e@gmx.net
In reply to: David E. Wheeler (#5)
Re: glob support in extension_control_path/dynamic_library_path?

On 24.06.26 17:34, David E. Wheeler wrote:

Peter E: what do you think about this as an evolution of the extension_control_path/dynamic_library_path work? Any gotchas to be aware of, aside from the current lack of Windows support?

Yes: Anything involving paths and wildcards is scary security-wise. I
would like to see some analysis about whether or how this is safe.

#7Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Peter Eisentraut (#6)
Re: glob support in extension_control_path/dynamic_library_path?

Security seems to be an interesting question for this.

The current patch simply takes a wildcard, and evaluates it every time it is needed. Is that the correct approach? The advantage is that when a new directory matching the pattern appears, it is automatically detected... but that's also the disadvantage.

Wouldn't it be better to freeze the current list of matching directories on configuration load, and require pg_reload_conf to add the newly matching patterns? With possibly additional helper functions that show what the patterns currently match compared to what's loaded by the active configuration? That's more complex, but could limit surprises.

Should it require ownership/permission checks on the pattern parts somehow, or some other limitation?

Also, while glob symbols are unlikely in filenames, they can be valid. Can backward compatibility be a possible concern, or accidental glob patterns from old configurations? For example a "/pg[18]/" directory would have a different meaning before/after.

+ glob_status = glob(mangled, GLOB_BRACE | GLOB_ERR, NULL, &globres

I think GLOB_BRACE isn't POSIX? Based on a quick search it isn't available on Solaris, for example.

#8Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Zsolt Parragi (#7)
Re: glob support in extension_control_path/dynamic_library_path?

Hello,

At Wed, 24 Jun 2026 14:19:33 -0700, Zsolt Parragi <zsolt.parragi@percona.com> wrote in

Security seems to be an interesting question for this.

The current patch simply takes a wildcard, and evaluates it every time
it is needed. Is that the correct approach? The advantage is that when
a new directory matching the pattern appears, it is automatically
detected... but that's also the disadvantage.

I understand the motivation, but I'm also a bit worried about allowing
glob patterns in paths searched for extension files.

Just a thought, but another approach would be to allow symlinks to
extension installation directories either in the existing extension
file search directories or in a separate directory added to the search
path. That would likely require PostgreSQL to recognize a somewhat
different extension file layout than it currently assumes, though.

Regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

#9David E. Wheeler
david@kineticode.com
In reply to: Zsolt Parragi (#7)
Re: glob support in extension_control_path/dynamic_library_path?

On Jun 24, 2026, at 17:19, Zsolt Parragi <zsolt.parragi@percona.com> wrote:

Security seems to be an interesting question for this.

The current patch simply takes a wildcard, and evaluates it every time
it is needed. Is that the correct approach? The advantage is that when
a new directory matching the pattern appears, it is automatically
detected... but that's also the disadvantage.

What’s the disadvantage, exactly? Sure, an attacker could stick a new directory in the wild-carded path and it will suddenly be available, but they can also just stick a dynamic library in any directory in a dynamic_library_path and it’ll be available. How is a wild carded directory worse than the current wildcarding, essentially, of DSOs and control files?

I suppose an attacker could add a directory that contains files with the same names as others, in the hopes they’d be found first in a search. We could potentially account for that by requiring that the directory have the same name as the control file being loaded, and for libraries perhaps allow “dir_name/filename” to ensure no other directory can replace it.

Wouldn't it be better to freeze the current list of matching
directories on configuration load, and require pg_reload_conf to add
the newly matching patterns? With possibly additional helper functions
that show what the patterns currently match compared to what's loaded
by the active configuration? That's more complex, but could limit
surprises.

I could see that. Limit it to the subdirectories found on startup or after the latest pg_reload_conf and report the delta (or just list what it found). Makes sense to me, assuming pg_reload_conf works as expected in environments like Postgres.app and CNPG (I don’t see why it wouldn’t).

Should it require ownership/permission checks on the pattern parts
somehow, or some other limitation?

Also, while glob symbols are unlikely in filenames, they can be valid.
Can backward compatibility be a possible concern, or accidental glob
patterns from old configurations? For example a "/pg[18]/" directory
would have a different meaning before/after.

Perhaps we could limit globbing to `*`?

+ glob_status = glob(mangled, GLOB_BRACE | GLOB_ERR, NULL, &globres

I think GLOB_BRACE isn't POSIX? Based on a quick search it isn't
available on Solaris, for example.

Best to use the standard, yeah.

Best,

David

#10David E. Wheeler
david@kineticode.com
In reply to: Kyotaro Horiguchi (#8)
Re: glob support in extension_control_path/dynamic_library_path?

On Jun 25, 2026, at 01:15, Kyotaro Horiguchi <horikyota.ntt@gmail.com> wrote:

Just a thought, but another approach would be to allow symlinks to
extension installation directories either in the existing extension
file search directories or in a separate directory added to the search
path. That would likely require PostgreSQL to recognize a somewhat
different extension file layout than it currently assumes, though.

I don’t follow the argument about symlinks, but suspect they wouldn’t work in environments like CNPG with read-only file systems.

But reorganizing where files live was exactly what I proposed in the Packaging & Lookup RFC[0]https://justatheory.com/2024/11/rfc-extension-packaging-lookup/#solution. It’s a *lot* more involved of a change, though, and has all sorts of compatibility challenges to work out.

[0]: https://justatheory.com/2024/11/rfc-extension-packaging-lookup/#solution

Best,

David

#11Zsolt Parragi
zsolt.parragi@percona.com
In reply to: David E. Wheeler (#9)
Re: glob support in extension_control_path/dynamic_library_path?

What’s the disadvantage, exactly? Sure, an attacker could stick a new directory in the wild-carded path and it will suddenly be available, but they can also just stick a dynamic library in any directory in a dynamic_library_path and it’ll be available. How is a wild carded directory worse than the current wildcarding, essentially, of DSOs and control files?

My main concern is observability: if you have a single directory, or a list of directories, it is clearly visible, it is relatively easy to argue about who can create files where. When we start adding wildcards anywhere on the path, and we can also have symlinks anywhere, it gets more difficult.

Providing admins a way to see the currently active paths, and also possibly making it fixed between config reloads could mitigate most of that.