Hi,

I'm investigating Alf Schlichting's report [1] of regression in ld.so
caused by my diff [2]. This regression reproduces on amd64-current too.

I found errors in my diff which break the dlclose/test1/prog2 test. But
what's really interesting -- is the dlclose/test1/prog3 test.

I found that with current ld.so, dlclose/test1/prog3 works because the
libaa and libbb are loaded as a "load group" because there is an
explicit dependency from libaa to libbb. If, however, the dependency
between shared objects is removed, like in the diff below -- the test
crashes both with and without my diff:

        ===> dlclose/test1/prog4
        ./prog4
        *** Signal SIGSEGV in dlclose/test1/prog4 (<bsd.regress.mk>:48 
'run-regress-prog4')
        FAILED
        *** Error 1 in target 'regress' (ignored)


If we read the dynamic symbol tables of both libraries, here's what we
see:

        $ readelf -sD libaa/libaa.so.1.0 libbb/libbb.so.1.0 | grep dup
           31  34: 0000000000000bc0     3    FUNC GLOBAL DEFAULT   8 
duplicateFun
           35  34: 0000000000000d10     6    FUNC GLOBAL DEFAULT   8 
duplicateFun

Both symbols are of "function" type and "global" binding.

Here's what SysV ABI [3] has to say regarding this about relocatable
objects:

        When the link editor combines several relocatable object files,
        it does not allow multiple definitions of STB_GLOBAL symbols with the
        same name.

But I think it makes sense to not allow this for shared objects too.
How can one expect a program to work correctly if there is a
collision between two shared objects which is silently ignored? This
also seems like an illegitimate way to replace some functionality of
another lib with your own...

Do you agree that when there are shared objects which have global-bound
function symbols with the same name -- ld.so must not allow such a
program to run/dlopen said shared objects?

[1] http://marc.info/?l=openbsd-ports&m=142901624010155&w=2
[2] http://marc.info/?l=openbsd-bugs&m=141653930524559&w=2
[3] http://www.sco.com/developers/gabi/latest/ch4.symtab.html


Index: regress/libexec/ld.so/dlclose//test1/Makefile
===================================================================
RCS file: /cvs/src/regress/libexec/ld.so/dlclose/test1/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- regress/libexec/ld.so/dlclose//test1/Makefile       30 Sep 2005 15:16:18 
-0000      1.2
+++ regress/libexec/ld.so/dlclose//test1/Makefile       7 May 2015 23:33:48 
-0000
@@ -1,5 +1,5 @@
 # $OpenBSD: Makefile,v 1.2 2005/09/30 15:16:18 kurt Exp $
 
-SUBDIR+= libbb libaa prog1 prog2 prog3
+SUBDIR+= libbb libaa libcc prog1 prog2 prog3 prog4
 
 .include <bsd.subdir.mk>
Index: regress/libexec/ld.so/dlclose//test1/Makefile.inc
===================================================================
RCS file: /cvs/src/regress/libexec/ld.so/dlclose/test1/Makefile.inc,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 Makefile.inc
--- regress/libexec/ld.so/dlclose//test1/Makefile.inc   28 Sep 2005 15:42:32 
-0000      1.1.1.1
+++ regress/libexec/ld.so/dlclose//test1/Makefile.inc   7 May 2015 23:33:48 
-0000
@@ -17,3 +17,12 @@ BB_OBJDIR!=  if [ -d $(BB_DIR)/${__objdir
                else \
                        echo "$(BB_DIR)"; \
                fi
+
+CC_DIR=${.CURDIR}/../libcc
+
+CC_OBJDIR!=    if [ -d $(CC_DIR)/${__objdir} ]; then \
+                       echo "$(CC_DIR)/${__objdir}"; \
+               else \
+                       echo "$(CC_DIR)"; \
+               fi
+
--- /dev/null   Fri May  8 02:41:30 2015
+++ regress/libexec/ld.so/dlclose/test1/libcc/Makefile  Mon Apr 20 00:12:26 2015
@@ -0,0 +1,9 @@
+#      $OpenBSD: Makefile,v 1.1.1.1 2005/09/28 15:42:32 kurt Exp $
+
+LIB=           cc
+SRCS=          cc.c
+LDADD+=                -Wl,-E
+
+regress: all
+
+.include <bsd.lib.mk>
--- /dev/null   Fri May  8 02:41:30 2015
+++ regress/libexec/ld.so/dlclose/test1/libcc/cc.c      Mon Apr 20 00:10:51 2015
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2005 Kurt Miller <k...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+int ccSymbol;
+
+int
+duplicateFun()
+{
+       return (0);
+}
+
--- /dev/null   Fri May  8 02:41:30 2015
+++ regress/libexec/ld.so/dlclose/test1/libcc/shlib_version     Mon Apr 20 
00:11:10 2015
@@ -0,0 +1,2 @@
+major=1
+minor=0 
--- /dev/null   Fri May  8 02:41:41 2015
+++ regress/libexec/ld.so/dlclose/test1/prog4/Makefile  Mon Apr 20 00:16:16 2015
@@ -0,0 +1,9 @@
+# $OpenBSD: Makefile,v 1.1.1.1 2005/09/30 15:14:46 kurt Exp $
+
+PROG=          prog4
+SRCS=          main.c
+LDFLAGS+=      -Wl,-E
+LDFLAGS+=      -Wl,-rpath,$(CC_OBJDIR)
+LDFLAGS+=      -Wl,-rpath,$(BB_OBJDIR)
+
+.include <bsd.regress.mk>
--- /dev/null   Fri May  8 02:41:41 2015
+++ regress/libexec/ld.so/dlclose/test1/prog4/main.c    Mon Apr 20 00:17:46 2015
@@ -0,0 +1,56 @@
+/*     $OpenBSD: main.c,v 1.1.1.1 2005/09/30 15:14:46 kurt Exp $       */
+
+/*
+ * Copyright (c) 2005 Kurt Miller <k...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+main()
+{
+       int ret = 0;
+       int (*bbTest2)(void);
+       void *libbb;
+       void *libcc;
+
+       libcc = dlopen("libcc.so", RTLD_LAZY|RTLD_GLOBAL);
+       libbb = dlopen("libbb.so", RTLD_LAZY|RTLD_GLOBAL);
+
+       if (libcc == NULL) {
+               printf("dlopen(\"libcc.so\", RTLD_LAZY|RTLD_GLOBAL) FAILED\n");
+               return (1);
+       }
+
+       if (libbb == NULL) {
+               printf("dlopen(\"libbb.so\", RTLD_LAZY|RTLD_GLOBAL) FAILED\n");
+               return (1);
+       }
+
+        bbTest2 = dlsym(libbb, "bbTest2");
+
+       /* call bbTest2 to force lazy binding to duplicateFun in libcc */
+        (*bbTest2)();
+
+       dlclose(libcc);
+
+       /* call bbTest2 again to ensure libcc was not unloaded (still needed) */
+        ret = (*bbTest2)();
+
+       dlclose(libbb);
+
+       return (ret);
+}

Reply via email to