Skip to content

Commit 2c2f248

Browse files
committed
xmlsec1: make crypto backend search relocatable
libltdl's lt_dlopenext() doesn't consult the calling binary's DT_RPATH or DT_RUNPATH. When xmlsec1 is shipped under $OMD_ROOT, libltdl instead finds the distro-installed /usr/lib/x86_64-linux-gnu/libxmlsec1-openssl and loads that, hitting an ABI mismatch against the bundled 1.3.8. We only get an error if there is a mismatch in versions of libxmlsec1-openssl on some platforms this worked previously without LD_LIBRARY_PATH being specified. Patched xmlsec1's src/dl.c to use dladdr() on a libxmlsec1 data symbol to locate libxmlsec1.so at runtime and register its directory via lt_dladdsearchdir(). libxmlsec1.so is installed which is the same directory that libxmlsec1-openssl.so is installed. libxmlsec1.so is loaded normally so using RUNPATH on the binrary is fine in this case. Drop force_rpath=True from xmlsec1_deployable_bin: the misleading "RPATH is required for dlopen()" comment was wrong for libltdl (which ignores both RPATH and RUNPATH), so RUNPATH on the binary is sufficient for its direct DT_NEEDED libs. Rewrite the BUILD comment accordingly. Also fix the same copy-pasted comment on nagios_bin_runpath: there force_rpath=True *is* justified, but for a different reason (DT_RPATH, unlike DT_RUNPATH, is inherited when the loader resolves transitive DT_NEEDED of dlopen()ed NEB modules). CMK-33201 Change-Id: Ie429875d434998998fa939dba69e56e7eed76b04 (cherry picked from commit 08b6cca)
1 parent 474adf2 commit 2c2f248

5 files changed

Lines changed: 84 additions & 5 deletions

File tree

MODULE.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,11 @@ snap7_repository(
414414
http_archive(
415415
name = "xmlsec1",
416416
build_file = "//omd/packages/xmlsec1:BUILD.xmlsec1.bazel",
417+
patch_args = ["-p1"],
418+
patch_tool = "patch",
419+
patches = [
420+
"//omd/packages/xmlsec1/patches:0001-relocatable-crypto-module-search.dif",
421+
],
417422
sha256 = "d0180916ae71be28415a6fa919a0684433ec9ec3ba1cc0866910b02e5e13f5bd",
418423
strip_prefix = "xmlsec1-1.3.8",
419424
urls = [

omd/packages/nagios/BUILD

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ pkg_filegroup(
6565
add_runpath(
6666
name = "nagios_bin_runpath",
6767
srcs = ["@nagios//:nagios_bin"],
68-
# nagios links libltdl to load NEB event broker modules. DT_RUNPATH is not
69-
# searched for dlopen() calls; DT_RPATH is required.
68+
# nagios dlopen()s NEB event broker modules (e.g. livestatus.o) with absolute
69+
# paths from nagios.cfg. That load doesn't consult this rpath, but DT_RPATH
70+
# (unlike DT_RUNPATH) is inherited when the loader resolves those modules'
71+
# own transitive DT_NEEDED. Kept as force_rpath so any NEB module whose
72+
# dependencies aren't reachable via its own runpath can still fall back to
73+
# $OMD_ROOT/lib.
7074
force_rpath = True,
7175
rpaths = ["$ORIGIN/../lib"],
7276
tags = ["manual"],

omd/packages/xmlsec1/BUILD

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ copy_file(
2929
set_runpath(
3030
name = "xmlsec1_deployable_bin",
3131
srcs = [":xmlsec1_bin_copy"],
32-
# xmlsec1 uses libltdl to dlopen() its crypto backend (libxmlsec1-openssl).
33-
# DT_RUNPATH is not searched for dlopen() calls; DT_RPATH is required.
34-
force_rpath = True,
32+
# RUNPATH here only resolves the binary's direct DT_NEEDED libs (libxmlsec1,
33+
# libltdl, libxml2, libxslt, libstdc++). The crypto backend (libxmlsec1-openssl)
34+
# is dlopen()ed by libltdl, which ignores RPATH/RUNPATH entirely -- that lookup
35+
# is handled by a source patch (see //omd/packages/xmlsec1/patches) which calls
36+
# lt_dladdsearchdir() with the libxmlsec1.so directory at runtime.
3537
rpaths = ["$ORIGIN/../lib"],
3638
tags = ["manual"],
3739
)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Make the crypto backend search relocatable.
2+
3+
libltdl does not consult the calling binary's DT_RPATH/DT_RUNPATH when
4+
resolving lt_dlopenext() modules; it uses LTDL_LIBRARY_PATH,
5+
LD_LIBRARY_PATH and the compiled-in sys_lib_dlsearch_path_spec. When
6+
xmlsec1 is shipped to a non-standard prefix (e.g. $OMD_ROOT/lib), the
7+
crypto backend (libxmlsec1-openssl.so) cannot be found, and libltdl
8+
may instead pick up a version from a distro-installed xmlsec1 in
9+
/usr/lib/x86_64-linux-gnu, with predictable ABI-mismatch failures.
10+
11+
Use dladdr() on a libxmlsec1 symbol to locate libxmlsec1.so itself and
12+
register the directory containing it with lt_dladdsearchdir(). The
13+
crypto backends are shipped alongside libxmlsec1.so, so this makes
14+
the install self-contained regardless of prefix, without relying on
15+
environment variables or wrapper scripts.
16+
17+
--- a/src/dl.c
18+
+++ b/src/dl.c
19+
@@ -6,6 +6,11 @@
20+
*
21+
* Copyright (C) 2002-2024 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
22+
*/
23+
+/* dladdr() is a GNU extension; needed here to locate libxmlsec1.so at runtime
24+
+ * so libltdl can find crypto backends bundled next to it. */
25+
+#ifndef _GNU_SOURCE
26+
+# define _GNU_SOURCE 1
27+
+#endif
28+
/**
29+
* SECTION:dl
30+
* @Short_description: Dynamic crypto-engine library loading functions.
31+
@@ -40,6 +45,12 @@
32+
#include <ltdl.h>
33+
#endif /* XMLSEC_DL_LIBLTDL */
34+
35+
+#if defined(XMLSEC_DL_LIBLTDL) && defined(__linux__)
36+
+#include <dlfcn.h>
37+
+#include <libgen.h>
38+
+#include <limits.h>
39+
+#endif /* XMLSEC_DL_LIBLTDL && __linux__ */
40+
+
41+
#if defined(XMLSEC_WINDOWS) && defined(XMLSEC_DL_WIN32)
42+
#include <windows.h>
43+
#endif /* defined(XMLSEC_WINDOWS) && defined(XMLSEC_DL_WIN32) */
44+
@@ -373,6 +384,24 @@ xmlSecCryptoDLInit(void) {
45+
xmlSecIOError("lt_dlinit", NULL, NULL);
46+
return(-1);
47+
}
48+
+
49+
+#if defined(__linux__)
50+
+ /* libltdl does not consult DT_RPATH/DT_RUNPATH of the calling binary.
51+
+ * Tell it about the directory that holds libxmlsec1.so so that crypto
52+
+ * backends shipped next to it are preferred over any system-installed
53+
+ * copies in /usr/lib. */
54+
+ {
55+
+ Dl_info info;
56+
+ char path[PATH_MAX];
57+
+ size_t len;
58+
+ if(dladdr((const void *)&gXmlSecCryptoDLLibraries, &info) != 0
59+
+ && info.dli_fname != NULL
60+
+ && (len = strlen(info.dli_fname)) < sizeof(path)) {
61+
+ memcpy(path, info.dli_fname, len + 1);
62+
+ (void)lt_dladdsearchdir(dirname(path));
63+
+ }
64+
+ }
65+
+#endif /* __linux__ */
66+
#endif /* XMLSEC_DL_LIBLTDL */
67+
68+
return(0);

omd/packages/xmlsec1/patches/BUILD

Whitespace-only changes.

0 commit comments

Comments
 (0)