Re: [sr #111358] libtool link with -dlpreopen fails with error: cannot find the library '' or unhandled argument
Roland Hughes via Discussion list for the GNU libtool shared library maintenance tool <[email protected]> Thu, 2 Apr 2026 08:58:21 -0500
| Newsgroups | gmane.comp.gnu.libtool.general |
|---|---|
| Organization | Logikal Solutions |
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
--------------CzwSodiNK9tsupzGOAG3OcRh
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Thank you for your time Patrice.
How do I officially open a bug on this? Use case is rather
straightforward. If you want code already set up for it
https://github.com/RolandHughes/ls-cs
I'm working in a different branch so master will be fine for you. Just
pull the code down then
sudo ./LsCs-Deb-build-dependencies.sh
just comment out the setting of RPATH in the xcb cmake files because
that will be first to fail.
src/plugins/imageformats/svg/svg.cmake:14: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/imageformats"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:83: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:164: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:261: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/playlistformats/playlistformats.cmake:9: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/playlistformats"
src/plugins/platforms/xcb/glx/xcb_glx.cmake:17: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/glx/xcb_glx.cmake:24: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/glx/xcb_glx.cmake:38: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/xcbglintegrations"
src/plugins/platforms/xcb/glx/xcb_glx.cmake:49: INSTALL_RPATH "$ORIGIN/../.."
src/plugins/platforms/xcb/xcb.cmake:11: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/xcb.cmake:18: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/xcb.cmake:32: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/platforms"
src/plugins/platforms/xcb/xcb.cmake:44: INSTALL_RPATH "$ORIGIN/../.."
src/plugins/sqldrivers/mysql/mysql.cmake:22: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"
src/plugins/sqldrivers/odbc/odbc.cmake:21: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"
src/plugins/sqldrivers/psql/psql.cmake:22: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"
Then just
build-LsCs-local.sh
That will build the entire library creating the following directory tree.
roland@mxz2g4:~/cups-stuff/LsCs_local_release/lib
$ tree
.
└── LsCs
├── cmake
│ ├── LsCsBinaryTargets.cmake
│ ├── LsCsBinaryTargets-debug.cmake
│ ├── LsCsConfig.cmake
│ ├── LsCsConfigVersion.cmake
│ ├── LsCsLibraryTargets.cmake
│ ├── LsCsLibraryTargets-debug.cmake
│ └── LsCsMacros.cmake
├── libLsCsCore.so -> libLsCsCore.so.0
├── libLsCsCore.so.0 -> libLsCsCore.so.0.3.2
├── libLsCsCore.so.0.3.2
├── libLsCsGui.so -> libLsCsGui.so.0
├── libLsCsGui.so.0 -> libLsCsGui.so.0.3.2
├── libLsCsGui.so.0.3.2
├── libLsCsMultimedia.so -> libLsCsMultimedia.so.0
├── libLsCsMultimedia.so.0 -> libLsCsMultimedia.so.0.3.2
├── libLsCsMultimedia.so.0.3.2
├── libLsCsNetwork.so -> libLsCsNetwork.so.0
├── libLsCsNetwork.so.0 -> libLsCsNetwork.so.0.3.2
├── libLsCsNetwork.so.0.3.2
├── libLsCsOpenGL.so -> libLsCsOpenGL.so.0
├── libLsCsOpenGL.so.0 -> libLsCsOpenGL.so.0.3.2
├── libLsCsOpenGL.so.0.3.2
├── libLsCsSql.so -> libLsCsSql.so.0
├── libLsCsSql.so.0 -> libLsCsSql.so.0.3.2
├── libLsCsSql.so.0.3.2
├── libLsCsSvg.so -> libLsCsSvg.so.0
├── libLsCsSvg.so.0 -> libLsCsSvg.so.0.3.2
├── libLsCsSvg.so.0.3.2
├── libLsCsXcbSupport.so -> libLsCsXcbSupport.so.0
├── libLsCsXcbSupport.so.0 -> libLsCsXcbSupport.so.0.3.2
├── libLsCsXcbSupport.so.0.3.2
├── libLsCsXmlPatterns.so -> libLsCsXmlPatterns.so.0
├── libLsCsXmlPatterns.so.0 -> libLsCsXmlPatterns.so.0.3.2
├── libLsCsXmlPatterns.so.0.3.2
├── libLsCsXml.so -> libLsCsXml.so.0
├── libLsCsXml.so.0 -> libLsCsXml.so.0.3.2
├── libLsCsXml.so.0.3.2
└── plugins
├── imageformats
│ └── LsCsImageFormatsSvg.so
├── mediaservices
│ ├── LsCsMultimedia_gst_audiodecoder.so
│ ├── LsCsMultimedia_gst_camerabin.so
│ └── LsCsMultimedia_gst_mediaplayer.so
├── platforms
│ └── LsCsGuiXcb.so
├── playlistformats
│ └── LsCsMultimedia_m3u.so
├── sqldrivers
│ ├── LsCsSqlMySql.so
│ ├── LsCsSqlOdbc.so
│ └── LsCsSqlPsql.so
└── xcbglintegrations
└── LsCsGuiXcb_Glx.so
10 directories, 47 files
roland@mxz2g4:~/cups-stuff/LsCs_local_release/lib
$
You will note that LsCsGuiXcb.so is in plugins/platforms under lib. It
needs library files from the lib directory above it, but, when installed
in a local tree, has no means of finding them without an insecure RPATH
hack.
The local script automatically builds everything in debug.
cd to examples directory then
./build-examples.sh
choose option to build all if you wish. You only need gui-hello.
console-hello doesn't use plugins so it works.
in src/core/plugin/qlibrary_unix.cpp around line 189 you will find a
bunch of commented out code pulling library paths from the .conf file
and inserting them into search path for lt_dlopen(). lines 256-267 are
the lines where it once again uses dlopen() but has commented out the
lt_dlopen() call.
USE_CASE:
lt_dlopen() should must use itself to open all library dependencies for
any library/plugin it is used to load. It's the perfect tool for secure
opens. A text .conf file is completely human/script auditable where as
baked in RPATHs are not.
When a plugin that is further down the directory tree is loaded with
lt_dlopen() if it needs library files from further up, this open fails,
even if those library paths are in the search path for lt_dlopen(). This
is because, per your source searches, the opening of dependencies is
being handed off to dlopen() not recursively handled by lt_dlopen() itself.
DO NOT YET HAVE COMMENTED OUT CODE FOR THIS
I swear I tested this, but don't see the code still remaining.
dlopen() does not search the cache/index until it has found the full
path to the library. Even if I pre-load
libLsCsCore.so.0.3.2
and all the other libraries the plugin needs dlopen() will fail without
the RPATH hack because the cache/index doesn't store just the library
name as above, but the full path. This is massive security hole because
MyExe could preload wholesome and pure libLsCsCore from the
trusted/vetted location and MyExe could call some other library method
that loads libLsCsCore from /home/Fred/malware-tree/lib/
I don't know what would break in the field (probably only compromised
programs) if the caching logic was changed.
COUNTER ARGUMENT
One could argue that allowing dynamic insertion like lt_dlopen() does is
a bigger security hole. Well:
1) they would have to know a program is using it.
2) have to make their insertion before everything to loaded.
3) programs using lt_dlopen() can block malicious same-name libraries
from getting loaded by having the main-line initialization code pre-load
all valid libraries. Some combination of lt_dlopenadvise() with
lt_dladvise_global() or, perhaps, lt_dlforeachfile() if one wishes to
brute force.
Thank you again for looking into this matter.
When I get done with converting this library to XMake and getting CUPS
3.x API support I was going to take another run at this dlopen()
situation. Better if someone familiar with the code takes a run at it.
Please let me know if you need write access to the repo so you can
create a GNU Testing branch that your team has access to. Yes, I know,
most people want a 5 line test program, but . . . this is mostly
watching scripts run.
On 4/2/2026 7:04 AM, Patrice Dumas wrote:
> Follow-up Comment #1, sr #111358 (group libtool):
>
> I had a look at the -dlpreopen use in the Debian code search, and this is used
> for in-source test executable linking and unless I missed something, I did not
> find any use with a library. I do not know if it this information is useful
> but it could explain why this has not already been reported.
>
>
> _______________________________________________________
>
> Reply to this item at:
>
> <https://savannah.gnu.org/support/?111358>
>
> _______________________________________________
> Message sent via Savannah
> https://savannah.gnu.org/
--
Roland Hughes, President
Logikal Solutions
(630)-205-1593 (cell)
https://theminimumyouneedtoknow.com
https://infiniteexposure.net
https://johnsmith-book.com
--------------CzwSodiNK9tsupzGOAG3OcRh
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Thank you for your time Patrice.</p>
<p>How do I officially open a bug on this? Use case is rather
straightforward. If you want code already set up for it</p>
<p><a class="moz-txt-link-freetext" href="https://github.com/RolandHughes/ls-cs">https://github.com/RolandHughes/ls-cs</a></p>
<p>I'm working in a different branch so master will be fine for you.
Just pull the code down then</p>
<pre>sudo ./LsCs-Deb-build-dependencies.sh</pre>
<p>just comment out the setting of RPATH in the xcb cmake files
because that will be first to fail.</p>
<pre>src/plugins/imageformats/svg/svg.cmake:14: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/imageformats"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:83: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:164: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/mediaservices/gstreamer/gstreamer.cmake:261: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/mediaservices"
src/plugins/multimedia/playlistformats/playlistformats.cmake:9: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/playlistformats"
src/plugins/platforms/xcb/glx/xcb_glx.cmake:17: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/glx/xcb_glx.cmake:24: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/glx/xcb_glx.cmake:38: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/xcbglintegrations"
src/plugins/platforms/xcb/glx/xcb_glx.cmake:49: INSTALL_RPATH "$ORIGIN/../.."
src/plugins/platforms/xcb/xcb.cmake:11: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/xcb.cmake:18: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
src/plugins/platforms/xcb/xcb.cmake:32: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/platforms"
src/plugins/platforms/xcb/xcb.cmake:44: INSTALL_RPATH "$ORIGIN/../.."
src/plugins/sqldrivers/mysql/mysql.cmake:22: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"
src/plugins/sqldrivers/odbc/odbc.cmake:21: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"
src/plugins/sqldrivers/psql/psql.cmake:22: INSTALL_RPATH "${LSCS_INST_PREFIX}/${LSCS_INST_LIB};${LSCS_INST_PREFIX}/${LSCS_INST_LIB}/plugins/sqldrivers"</pre>
<p>Then just</p>
<pre>build-LsCs-local.sh</pre>
<p>That will build the entire library creating the following
directory tree.</p>
<pre>roland@mxz2g4:~/cups-stuff/LsCs_local_release/lib
$ tree
.
└── LsCs
├── cmake
│ ├── LsCsBinaryTargets.cmake
│ ├── LsCsBinaryTargets-debug.cmake
│ ├── LsCsConfig.cmake
│ ├── LsCsConfigVersion.cmake
│ ├── LsCsLibraryTargets.cmake
│ ├── LsCsLibraryTargets-debug.cmake
│ └── LsCsMacros.cmake
├── libLsCsCore.so -> libLsCsCore.so.0
├── libLsCsCore.so.0 -> libLsCsCore.so.0.3.2
├── libLsCsCore.so.0.3.2
├── libLsCsGui.so -> libLsCsGui.so.0
├── libLsCsGui.so.0 -> libLsCsGui.so.0.3.2
├── libLsCsGui.so.0.3.2
├── libLsCsMultimedia.so -> libLsCsMultimedia.so.0
├── libLsCsMultimedia.so.0 -> libLsCsMultimedia.so.0.3.2
├── libLsCsMultimedia.so.0.3.2
├── libLsCsNetwork.so -> libLsCsNetwork.so.0
├── libLsCsNetwork.so.0 -> libLsCsNetwork.so.0.3.2
├── libLsCsNetwork.so.0.3.2
├── libLsCsOpenGL.so -> libLsCsOpenGL.so.0
├── libLsCsOpenGL.so.0 -> libLsCsOpenGL.so.0.3.2
├── libLsCsOpenGL.so.0.3.2
├── libLsCsSql.so -> libLsCsSql.so.0
├── libLsCsSql.so.0 -> libLsCsSql.so.0.3.2
├── libLsCsSql.so.0.3.2
├── libLsCsSvg.so -> libLsCsSvg.so.0
├── libLsCsSvg.so.0 -> libLsCsSvg.so.0.3.2
├── libLsCsSvg.so.0.3.2
├── libLsCsXcbSupport.so -> libLsCsXcbSupport.so.0
├── libLsCsXcbSupport.so.0 -> libLsCsXcbSupport.so.0.3.2
├── libLsCsXcbSupport.so.0.3.2
├── libLsCsXmlPatterns.so -> libLsCsXmlPatterns.so.0
├── libLsCsXmlPatterns.so.0 -> libLsCsXmlPatterns.so.0.3.2
├── libLsCsXmlPatterns.so.0.3.2
├── libLsCsXml.so -> libLsCsXml.so.0
├── libLsCsXml.so.0 -> libLsCsXml.so.0.3.2
├── libLsCsXml.so.0.3.2
└── plugins
├── imageformats
│ └── LsCsImageFormatsSvg.so
├── mediaservices
│ ├── LsCsMultimedia_gst_audiodecoder.so
│ ├── LsCsMultimedia_gst_camerabin.so
│ └── LsCsMultimedia_gst_mediaplayer.so
├── platforms
│ └── LsCsGuiXcb.so
├── playlistformats
│ └── LsCsMultimedia_m3u.so
├── sqldrivers
│ ├── LsCsSqlMySql.so
│ ├── LsCsSqlOdbc.so
│ └── LsCsSqlPsql.so
└── xcbglintegrations
└── LsCsGuiXcb_Glx.so
10 directories, 47 files
roland@mxz2g4:~/cups-stuff/LsCs_local_release/lib
$ </pre>
<p><br>
You will note that LsCsGuiXcb.so is in plugins/platforms under
lib. It needs library files from the lib directory above it, but,
when installed in a local tree, has no means of finding them
without an insecure RPATH hack.</p>
<p>The local script automatically builds everything in debug.</p>
<p>cd to examples directory then</p>
<pre>./build-examples.sh</pre>
<p>choose option to build all if you wish. You only need gui-hello.
console-hello doesn't use plugins so it works.</p>
<p>in src/core/plugin/qlibrary_unix.cpp around line 189 you will
find a bunch of commented out code pulling library paths from the
.conf file and inserting them into search path for lt_dlopen().
lines 256-267 are the lines where it once again uses dlopen() but
has commented out the lt_dlopen() call.</p>
<p>USE_CASE:</p>
<p>lt_dlopen() should must use itself to open all library
dependencies for any library/plugin it is used to load. It's the
perfect tool for secure opens. A text .conf file is completely
human/script auditable where as baked in RPATHs are not.</p>
<p>When a plugin that is further down the directory tree is loaded
with lt_dlopen() if it needs library files from further up, this
open fails, even if those library paths are in the search path for
lt_dlopen(). This is because, per your source searches, the
opening of dependencies is being handed off to dlopen() not
recursively handled by lt_dlopen() itself.</p>
<p>DO NOT YET HAVE COMMENTED OUT CODE FOR THIS</p>
<p>I swear I tested this, but don't see the code still remaining.</p>
<p>dlopen() does not search the cache/index until it has found the
full path to the library. Even if I pre-load </p>
<pre>libLsCsCore.so.0.3.2</pre>
<p>and all the other libraries the plugin needs dlopen() will fail
without the RPATH hack because the cache/index doesn't store just
the library name as above, but the full path. This is massive
security hole because MyExe could preload wholesome and pure
libLsCsCore from the trusted/vetted location and MyExe could call
some other library method that loads libLsCsCore from
/home/Fred/malware-tree/lib/</p>
<p>I don't know what would break in the field (probably only
compromised programs) if the caching logic was changed.</p>
<p>COUNTER ARGUMENT</p>
<p>One could argue that allowing dynamic insertion like lt_dlopen()
does is a bigger security hole. Well:</p>
<p>1) they would have to know a program is using it.</p>
<p>2) have to make their insertion before everything to loaded.</p>
<p>3) programs using lt_dlopen() can block malicious same-name
libraries from getting loaded by having the main-line
initialization code pre-load all valid libraries. Some combination
of lt_dlopenadvise() with lt_dladvise_global() or, perhaps,
lt_dlforeachfile() if one wishes to brute force.</p>
<p>Thank you again for looking into this matter.</p>
<p>When I get done with converting this library to XMake and getting
CUPS 3.x API support I was going to take another run at this
dlopen() situation. Better if someone familiar with the code takes
a run at it.</p>
<p>Please let me know if you need write access to the repo so you
can create a GNU Testing branch that your team has access to. Yes,
I know, most people want a 5 line test program, but . . . this is
mostly watching scripts run.</p>
<p><br>
</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 4/2/2026 7:04 AM, Patrice Dumas
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:[email protected]">
<pre wrap="" class="moz-quote-pre">Follow-up Comment #1, sr #111358 (group libtool):
I had a look at the -dlpreopen use in the Debian code search, and this is used
for in-source test executable linking and unless I missed something, I did not
find any use with a library. I do not know if it this information is useful
but it could explain why this has not already been reported.
_______________________________________________________
Reply to this item at:
<a class="moz-txt-link-rfc2396E" href="https://savannah.gnu.org/support/?111358"><https://savannah.gnu.org/support/?111358></a>
_______________________________________________
Message sent via Savannah
<a class="moz-txt-link-freetext" href="https://savannah.gnu.org/">https://savannah.gnu.org/</a>
</pre>
</blockquote>
<pre class="moz-signature" cols="72">--
Roland Hughes, President
Logikal Solutions
(630)-205-1593 (cell)
<a class="moz-txt-link-freetext" href="https://theminimumyouneedtoknow.com">https://theminimumyouneedtoknow.com</a>
<a class="moz-txt-link-freetext" href="https://infiniteexposure.net">https://infiniteexposure.net</a>
<a class="moz-txt-link-freetext" href="https://johnsmith-book.com">https://johnsmith-book.com</a></pre>
</body>
</html>
--------------CzwSodiNK9tsupzGOAG3OcRh--