Re: lt_dlopen an uninstalled library

2021-11-25 Thread Bob Friesenhahn

On Thu, 25 Nov 2021, ilya Basin wrote:


Loading modules is an extremely security-sensitive issue so it makes sense to 
require that the specified path be absolute


I agree. Actually I haven't told the whole truth. My goal was to 
[mis]use libtool to load dynamically a regular library that is 
supposed to be in /usr/lib/ on Unix and at the same folder as .exe 
on Windows. The reason I don't link with it is my library depends on 
some other libraries that are not in the search path and my 
executable loads them first, then loads my library. This is why a 
wrapper script would solve it.


Years ago, Gary V. Vaughan (a key libtool developer) suggested to me 
that dlopen() is quite portable across Unix-like systems (even Apple's 
OS X) and that libltdl is not really necessarily needed in order to 
load dynamic modules/modules.  This leaves Microsoft Windows for which 
it it is relatively easy to use its similar facilities via 
LoadLibrary()/FreeLibrary().


It is true that libltdl will help on systems where library 
dependencies do not work properly, or where special compiler options 
must be used, and it can be used to emulate a loadable module in 
static builds.


Libtool is exceedingly helpful when it is desired to be able to 
support static builds and it also helps for compiling shared libraries 
(DLLs) under Microsoft Windows.


So it is worth considering using dlopen() directly.

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/
Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt



Re: lt_dlopen an uninstalled library

2021-11-25 Thread ilya Basin
> Loading modules is an extremely security-sensitive issue so it makes sense to 
> require that the specified path be absolute

I agree. Actually I haven't told the whole truth. My goal was to [mis]use 
libtool to load dynamically a regular library that is supposed to be in 
/usr/lib/ on Unix and at the same folder as .exe on Windows. The reason I don't 
link with it is my library depends on some other libraries that are not in the 
search path and my executable loads them first, then loads my library. This is 
why a wrapper script would solve it.

It would be gread if an option existed in libtool to force a wrapper script 
even if we don't link with any uninstalled libraries.

On 25.11.2021 2:15, Bob Friesenhahn wrote:
> On Thu, 25 Nov 2021, ilya Basin wrote:
> 
>> Hi Bob. I configured the GM build with '--with-modules', ran `make check` 
>> successfully. Then truncated the built .so files inside the 'coders/' dir to 
>> break it. Then reproduced the failure in gdb
>>
>>    [il@reallin GM]$ export 
>> MAGICK_CONFIGURE_PATH='/home/il/builds/GM/config:/home/il/builds/GM/config'
>>    [il@reallin GM]$ export 
>> MAGICK_CODER_MODULE_PATH='/home/il/builds/GM/coders'
>>    [il@reallin GM]$ gdb --args ./tests/.libs/lt-constitute -storagetype char 
>> /home/il/builds/GM/tests/input_truecolor.miff bgr
>>
>> So it turned out that the test program relies on the full path to the 
>> modules dir passed to the program and it calls lt_dlopen() with the full 
>> path. I guess I'll have to set the test environment in Makefile.am. Thanks.
> 
> It is interesting that this is what was causing problems for you. Loading 
> modules is an extremely security-sensitive issue so it makes sense to require 
> that the specified path be absolute, or written like ./foo.la.
> 
> Regardless, GraphicsMagick does some things differently than perhaps the 
> original libtool/libltdl objectives since it tries not to be too dependent on 
> libltdl and it has its own module loader smarts.
> 
> Bob



Re: lt_dlopen an uninstalled library

2021-11-24 Thread Bob Friesenhahn

On Thu, 25 Nov 2021, ilya Basin wrote:


Hi Bob. I configured the GM build with '--with-modules', ran `make check` 
successfully. Then truncated the built .so files inside the 'coders/' dir to 
break it. Then reproduced the failure in gdb

   [il@reallin GM]$ export 
MAGICK_CONFIGURE_PATH='/home/il/builds/GM/config:/home/il/builds/GM/config'
   [il@reallin GM]$ export MAGICK_CODER_MODULE_PATH='/home/il/builds/GM/coders'
   [il@reallin GM]$ gdb --args ./tests/.libs/lt-constitute -storagetype char 
/home/il/builds/GM/tests/input_truecolor.miff bgr

So it turned out that the test program relies on the full path to 
the modules dir passed to the program and it calls lt_dlopen() with 
the full path. I guess I'll have to set the test environment in 
Makefile.am. Thanks.


It is interesting that this is what was causing problems for you. 
Loading modules is an extremely security-sensitive issue so it makes 
sense to require that the specified path be absolute, or written like 
./foo.la.


Regardless, GraphicsMagick does some things differently than perhaps 
the original libtool/libltdl objectives since it tries not to be too 
dependent on libltdl and it has its own module loader smarts.


Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/
Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt



Re: lt_dlopen an uninstalled library

2021-11-24 Thread ilya Basin
Hi Bob. I configured the GM build with '--with-modules', ran `make check` 
successfully. Then truncated the built .so files inside the 'coders/' dir to 
break it. Then reproduced the failure in gdb

[il@reallin GM]$ export 
MAGICK_CONFIGURE_PATH='/home/il/builds/GM/config:/home/il/builds/GM/config'
[il@reallin GM]$ export MAGICK_CODER_MODULE_PATH='/home/il/builds/GM/coders'
[il@reallin GM]$ gdb --args ./tests/.libs/lt-constitute -storagetype char 
/home/il/builds/GM/tests/input_truecolor.miff bgr

So it turned out that the test program relies on the full path to the modules 
dir passed to the program and it calls lt_dlopen() with the full path. I guess 
I'll have to set the test environment in Makefile.am. Thanks.

┌─magick/module.c──┐
│ 1419  (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),│
│ 1420"Opening module at path \"%s\" ...", path);  │
│ 1421 │
│  >  1422  handle=lt_dlopen(path);│
│ 1423  if (handle == (ModuleHandle) NULL) │
│ 1424{│
│ 1425  FormatString(message,"\"%.1024s: %.1024s\"",path,lt_dlerror│
│ 1426  ThrowException(exception,ModuleError,UnableToLoadModule,mes│
│ 1427  return(MagickFail);│
│ 1428}│
│ 1429  /* │
└──┘
multi-thre Thread 0x773cc8 In: OpenModule  L1422 PC: 0x77e7bc6c 
(gdb) print path
$1 = "/.snapshots/persist/builds/GM/coders/miff.la\000\000\000\000\313|VUUU\000\
(gdb) 


On 23.11.2021 20:31, Bob Friesenhahn wrote:
> On Mon, 22 Nov 2021, ilya Basin wrote:
> 
>> Hi List.
>> I'm making a program with plugins as shared libraries and when I run `make 
>> check` I want my program to load the uninstalled plugins using lt_dlopen().
>>
>> I expected that passing `-dlopen libname.la` to libtool would force the 
>> generation of a wrapper script setting the proper LD_LIBRARY_PATH (just like 
>> regular linking with a shared .la does). However, an ELF binary is generated 
>> and and attempt to call lt_dlopen("libname.la") fails with "File not found". 
>> It only succeeds if the filename contains "./.libs/". What am I doing wrong?
> 
> I am not sure what the correct answer is.  Normally loadable modules do not 
> have "lib" prefixes and so normally one does not use a "lib" prefix in 
> conjunction with -module.  Use of "lib" prefixes is for shared libraries 
> indended to be linked with using a linker (for software compilation).
> 
> When libtool builds shared libraries and modules, it puts them in a ".libs" 
> subdirectory.  The ".la" file in the build directory should be enough for 
> libltdl to load the module from the hidden ".libs" subdirectory.  When the 
> module is installed, the a new ".la" file is created which is correct for the 
> installed form, and the module may be re-linked while being installed.
> 
> Feel free to look at GraphicsMagick (http://www.GraphicsMagick.org/) source 
> code for ideas.  GraphicsMagick uses lots of modules and its test suite works 
> without installing the software.  It does not use libltdl's static-module 
> "preloaded" feature.
> 
> Bob



Re: lt_dlopen an uninstalled library

2021-11-23 Thread Roumen Petrov

Hi ilya,

ilya Basin wrote:

Hi List.
I'm making a program with plugins as shared libraries and when I run `make 
check` I want my program to load the uninstalled plugins using lt_dlopen().

I expected that passing `-dlopen libname.la` to libtool would force the generation of a wrapper script 
setting the proper LD_LIBRARY_PATH (just like regular linking with a shared .la does). However, an ELF binary 
is generated and and attempt to call lt_dlopen("libname.la") fails with "File not found". 
It only succeeds if the filename contains "./.libs/". What am I doing wrong?


No idea.

Just one note that environment variable is LTDL_LIBRARY_PATH - dynamically load 
libtool library.
Path for shared libraries depend from OS.

[SNIP]

Roumen



Re: lt_dlopen an uninstalled library

2021-11-23 Thread Bob Friesenhahn

On Mon, 22 Nov 2021, ilya Basin wrote:


Hi List.
I'm making a program with plugins as shared libraries and when I run `make 
check` I want my program to load the uninstalled plugins using lt_dlopen().

I expected that passing `-dlopen libname.la` to libtool would force 
the generation of a wrapper script setting the proper 
LD_LIBRARY_PATH (just like regular linking with a shared .la does). 
However, an ELF binary is generated and and attempt to call 
lt_dlopen("libname.la") fails with "File not found". It only 
succeeds if the filename contains "./.libs/". What am I doing wrong?


I am not sure what the correct answer is.  Normally loadable modules 
do not have "lib" prefixes and so normally one does not use a "lib" 
prefix in conjunction with -module.  Use of "lib" prefixes is for 
shared libraries indended to be linked with using a linker (for 
software compilation).


When libtool builds shared libraries and modules, it puts them in a 
".libs" subdirectory.  The ".la" file in the build directory should be 
enough for libltdl to load the module from the hidden ".libs" 
subdirectory.  When the module is installed, the a new ".la" file is 
created which is correct for the installed form, and the module may be 
re-linked while being installed.


Feel free to look at GraphicsMagick (http://www.GraphicsMagick.org/) 
source code for ideas.  GraphicsMagick uses lots of modules and its 
test suite works without installing the software.  It does not use 
libltdl's static-module "preloaded" feature.


Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/
Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt



Re: lt_dlopen an uninstalled library

2021-11-22 Thread Luke Mewburn
On 21-11-22 23:33, ilya Basin wrote:
  | Hi List.
  | I'm making a program with plugins as shared libraries and when I run
  | `make check` I want my program to load the uninstalled plugins using
  | lt_dlopen().
  | 
  | I expected that passing `-dlopen libname.la` to libtool would force
  | the generation of a wrapper script setting the proper
  | LD_LIBRARY_PATH (just like regular linking with a shared .la does).
  | However, an ELF binary is generated and and attempt to call
  | lt_dlopen("libname.la") fails with "File not found". It only
  | succeeds if the filename contains "./.libs/". What am I doing wrong?


I think you'll find it's less hassle to extend your testsuite setup to
install the library into the testsuite working area before performing
other tests, using a "make DESTDIR=working/area/some/subdir install".
I do this for other components too, such as python extension shared
libraries.

Then just set your LD_LIBRARY_PATH, PYTHONPATH (etc) to the
relevant testsuite working area, before running the other tests.


  | 
  | Makefile.am:
  | 
  | bin_PROGRAMS = purplecat
  | purplecat_SOURCES = main.c
  | 
  | purplecat_LDADD = \
  | -dlopen libpurplecat.la \
  | -lltdl \
  | $(MY_NULL)
  | 
  | lib_LTLIBRARIES = libpurplecat.la
  | 
  | libpurplecat_la_SOURCES = \
  | purplecat.h \
  | purplecat.c \
  | $(MY_NULL)
  | 
  | libpurplecat_la_LDFLAGS = -module
  | 
  | 
  | main.c:
  | 
  | int main(int argc, char *argv[]) {
  | static const char *filename = "libpurplecat";
  | static int (*p_pcat_main)(int argc, char *argv[]);
  | int res;
  | lt_dlinit();
  | lt_dlhandle handle = lt_dlopenext(filename);
  | if (!handle) {
  | fprintf(stderr, "Failed to load '%s': %s\n", filename, 
lt_dlerror());
  | return 1;
  | }
  | p_pcat_main = lt_dlsym(handle, "pcat_main");
  | res = p_pcat_main(argc, argv);
  | lt_dlclose(handle);
  | return res;
  | }
  | 



regards,
Luke.