I'm trying to create a capsicum sandbox to load plugins. Most of the setup is ready and working:
fork()
.From child:
cap_enter()
.fdlopen()
.This setup is working when the plugin is self-contained (the required symbols are already present in the running program). However if the plugin depends on some system library, it fails to load. FreeBSD's rtld offers the environment variable LD_LIBRARY_PATH_FDS
as an extra path for library paths that work under capsicum mode. I can set this environment variable within the C program from the child process.
I'd like to query the library search path for the current process (not a toolchain or whatever, but the current program) so I can open these file descriptors before I call cap_enter()
. How do I make such query from a C program?
I'd like to query the library search path for the current process (not a toolchain or whatever, but the current program) so I can open these file descriptors before I call
cap_enter()
. How do I make such query from a C program?
Dynamic library search path is not a property of the process per se. It is a property of each DSO, including that of the executable. The concept is meaningless for processes running static executables.
You can get a handle on the main executable by calling dlopen()
with a null filename argument:
void *main_object = dlopen(NULL, RTLD_LAZY | RTLD_NOLOAD);
You can then use dlinfo()
to obtain the library search paths for that object. I think that will include the system's default search paths, any specified via relevant environment variables, any specified in the executable's own DSO, and maybe any specified in other DSOs already loaded in the current process. Something like this:
Dl_serinfo search_info_size;
Dl_serinfo *search_info;
int result = dlinfo(main_object, RTLD_DI_SERINFOSIZE, &search_info_size);
search_info = malloc(search_info_size.dls_size);
result = dlinfo(main_object, RTLD_DI_SERINFOSIZE, &search_info);
result = dlinfo(main_object, RTLD_DI_SERINFO, &search_info);
The details of that procedure are drawn from the Linux manual page, which goes into more detail than the FreeBSD one. Error checks have been omitted for brevity.
Having done that, you can find the search paths as the search_info->dls_cnt
elements of search_info->dls_serpath
. Consult the manual for more details.
The above answers the question posed, but do note, however, that it is possible for a shared object that has not yet been loaded to have additional library directories encoded in it that the main executable does not (yet) know about. In such a case, ensuring all the directories in the main executable's search paths accessible might not be enough to load the additional object.