Re: [rtld] fdlopen(), fdlputpath() and capsicum

From: Konstantin Belousov <kib_at_freebsd.org>
Date: Thu, 31 Oct 2024 06:08:16 UTC
On Thu, Oct 31, 2024 at 02:18:11AM -0300, Vinícius dos Santos Oliveira wrote:
> I'm trying to use capsicum to load untrusted plugins (fdlopen after
> cap_enter), but I've been facing problems as plugins might depend on
> not yet loaded libraries (LD_LIBRARY_PATH no longer works after we
> disable ambient authority).
> 
> 10 years ago rtld gained the option/env-var to specify directory
> descriptors to be searched instead[1].
> 
> However this env-var is only queried at program startup (the use case
> is not sandboxing plugins through fdlopen(), but whole programs
> through exec()). exec() is not an option for my use case. Plugins are
> meant to load functions that extend the current program image (e.g.
> manipulating data structures or some shared memory). exec() would just
> kill any use I have for plugins.
> 
> My project just stalled on this problem this week. A workaround I've
> been planning was to statically link the plugins to the libraries
> (they are untrusted, so this step would occur in a jail), but this
> won't be an option for every plugin (maybe closed source, maybe
> licensing problems for the library linked with, ...).
> 
> I'd like to request a new function to use from C programs:
> 
> int fdlputpath(int fd);
> 
> fdlputpath() would just modify the private variable ld_library_dirs
> introduced in the commit which introduced the env var
> LD_LIBRARY_PATH_FDS. fdlputpath() would have some restrictions similar
> to putenv[2][3][4].
> 
> The change is simple and it'd open the doors to use fdlopen() for
> capsicum processes.
> 
> Thoughts?
> 
> [1] https://git.quacker.org/d/freebsd-nq/commit/02d3b38e0a766bde374de052a2c65a095282f302?style=unified&whitespace=ignore-all&show-outdated=
> [2] putenv() modifies a global and it's not thread-safe. fdlputpath()
> would have the same restriction.
> [3] It's not safe to deallocate old values inserted by previous calls
> to putenv() as copies/references to old values might be hanging
> around. fdlputpath() would have the same restriction.
> [4] Some implementations of putenv() might provoke intentional leaks
> to avoid the previous problem. Users of fdlputpath() might adopt a
> similar approach and keep the passed values hanging around as valid
> resources forever just in case.

Try this https://reviews.freebsd.org/D47351