lib/replace: avoid using libbsd for builtin linking
authorStefan Metzmacher <metze@samba.org>
Tue, 12 Sep 2023 13:22:03 +0000 (15:22 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 16 Oct 2023 08:23:15 +0000 (10:23 +0200)
This is similar to commit 66e90b7391bd404580f3919c4f2b8625c9c89c0e:
nsswitch: reduce dependecies to private libraries and link static/builtin if possible

There we tried to hide our internal symbols from applications loading
our plugins (e.g. libnss_winbind.so.2 or pam_winbind.so)

If we find libbsd in the system we link our plugins against it
and inject the symbols from it into the application, as the
symbols in libbsd have very common names, there's a change to
generate symbol conflicts causing unexpected behavior.

So we better use our own replacement functions from lib/replace
for the plugins instead of using the ones from libbsd
as we most likely not really need them. Currently we only
seem to use strlcpy() and we have our own version of it...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15475

Signed-off-by: Stefan Metzmacher <metze@samba.org>
lib/replace/replace.h
lib/replace/replace_builtin_linking.h [new file with mode: 0644]
lib/replace/wscript

index a6a2b40777f3c932ca6839a08a31998cc295acb1..d2ce65bdcb61d2cb566e4907cce1db9d826aad47 100644 (file)
 #include "config.h"
 #endif
 
+#ifdef _SAMBA_BUILTIN_LINKING_
+#include "replace_builtin_linking.h"
+#endif /* _SAMBA_BUILTIN_LINKING_ */
+
 #ifdef HAVE_STANDARDS_H
 #include <standards.h>
 #endif
diff --git a/lib/replace/replace_builtin_linking.h b/lib/replace/replace_builtin_linking.h
new file mode 100644 (file)
index 0000000..d645726
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _REPLACE_BUILTIN_LINKING_H_
+#define _REPLACE_BUILTIN_LINKING_H_
+
+/*
+ * In the builtin case we don't want to depend on
+ * libbsd as that would inject a lot of symbols
+ * with very common names including crypto related
+ * stuff, we want to avoid that for builtin linking
+ * of plugins.
+ */
+
+#ifdef HAVE_STRLCPY_IN_LIBBSD
+#undef HAVE_STRLCPY
+#undef HAVE_STRLCAT
+#endif /* HAVE_STRLCPY_IN_LIBBSD */
+
+#ifdef HAVE_CLOSEFROM_IN_LIBBSD
+#undef HAVE_CLOSEFROM
+#endif /* HAVE_CLOSEFROM_IN_LIBBSD */
+
+#ifdef HAVE_GETPEEREID_IN_LIBBSD
+#undef HAVE_GETPEEREID
+#endif /* HAVE_GETPEEREID_IN_LIBBSD */
+
+#ifdef HAVE_SETPROCTITLE_IN_LIBBSD
+#undef HAVE_SETPROCTITLE
+#endif /* HAVE_SETPROCTITLE_IN_LIBBSD */
+#ifdef HAVE_SETPROCTITLE_INIT_IN_LIBBSD
+#undef HAVE_SETPROCTITLE_INIT
+#endif /* HAVE_SETPROCTITLE_INIT_IN_LIBBSD */
+
+#endif /* _REPLACE_BUILTIN_LINKING_H_ */
index 77e655bb68b3bf29148bb52af9641dc25f97c716..7c43e0d262900658d6eeec7dcd548f8c60efb4db 100644 (file)
@@ -447,7 +447,9 @@ def configure(conf):
     if not conf.CHECK_FUNCS('strlcpy strlcat'):
         if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h',
                                checklibc=True):
+            conf.DEFINE('HAVE_STRLCPY_IN_LIBBSD', 1)
             strlcpy_in_bsd = True
+            libbsd_useful = True
     elif conf.env.enable_fuzzing:
         # Just to complicate it more, some versions of Honggfuzz have
         # got strlcpy and strlcat in libc, but not in <string.h>
@@ -460,14 +462,25 @@ def configure(conf):
         conf.CHECK_HEADERS('bsd/string.h')
 
     if not conf.CHECK_FUNCS('getpeereid'):
-        conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h')
+        if conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h'):
+            conf.DEFINE('HAVE_GETPEEREID_IN_LIBBSD', 1)
+            libbsd_useful = True
     if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'):
-        conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h')
+        if conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h'):
+            conf.DEFINE('HAVE_SETPROCTITLE_IN_LIBBSD', 1)
+            libbsd_useful = True
     if not conf.CHECK_FUNCS('setproctitle_init'):
-        conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h')
+        if conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h'):
+            conf.DEFINE('HAVE_SETPROCTITLE_INIT_IN_LIBBSD', 1)
+            libbsd_useful = True
 
     if not conf.CHECK_FUNCS('closefrom'):
-        conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h')
+        if conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h'):
+            conf.DEFINE('HAVE_CLOSEFROM_IN_LIBBSD', 1)
+            libbsd_useful = True
+
+    if libbsd_useful:
+        conf.DEFINE('REPLACE_USE_LIBBSD', 1)
 
     conf.CHECK_CODE('''
                 struct ucred cred;
@@ -913,10 +926,20 @@ def build(bld):
                 break
 
     extra_libs = ''
-    if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd'
     if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt'
     if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl'
 
+    # In the builtin case we don't want to depend on
+    # libbsd as that would inject a lot of symbols
+    # with very common names including crypto related
+    # stuff, we want to avoid that for builtin linking
+    # of plugins.
+    REPLACE_BUILTIN_SOURCE = REPLACE_HOSTCC_SOURCE
+    REPLACE_BUILTIN_SOURCE += ' closefrom.c'
+    REPLACE_BUILTIN_DEPS = extra_libs
+
+    if bld.CONFIG_SET('REPLACE_USE_LIBBSD'): extra_libs += ' bsd'
+
     if not bld.CONFIG_SET('HAVE_CLOSEFROM'):
         REPLACE_HOSTCC_SOURCE += ' closefrom.c'
 
@@ -957,6 +980,8 @@ def build(bld):
                       # hide_symbols=bld.BUILTIN_LIBRARY('replace'),
                       private_library=True,
                       provide_builtin_linking=True,
+                      builtin_source=REPLACE_BUILTIN_SOURCE,
+                      builtin_deps='dl attr' + REPLACE_BUILTIN_DEPS,
                       deps='dl attr' + extra_libs)
 
     replace_test_cflags = ''