Subject: bin/6139: ld.so uses lib with wrong major version if LD_LIBRARY_PATH set
To: None <gnats-bugs@gnats.netbsd.org>
From: Dave Huang <khym@bga.com>
List: netbsd-bugs
Date: 09/11/1998 00:24:09
>Number:         6139
>Category:       bin
>Synopsis:       ld.so uses lib with wrong major version if LD_LIBRARY_PATH set
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Sep 10 22:35:00 1998
>Last-Modified:
>Originator:     Dave Huang
>Organization:
Name: Dave Huang     |   Mammal, mammal / their names are called /
INet: khym@bga.com   |   they raise a paw / the bat, the cat /
FurryMUCK: Dahan     |   dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 22 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++
>Release:        NetBSD-current as of September 10, 1998
>Environment:
	
System: NetBSD dahan.metonymy.com 1.3H NetBSD 1.3H (SPIFF) #249: Wed Sep 9 16:25:32 CDT 1998 khym@dahan.metonymy.com:/usr/src.local/sys/arch/i386/compile/SPIFF i386


>Description:
	If LD_LIBRARY_PATH is set, the a.out ld.so will attempt to use
a library with a different major version number than the one specified
in the executable (if there is one).
>How-To-Repeat:
	a.out is linked against libstdc++.so.0.1. I have
libstdc++.so.0.1, libstdc++.so.1.0, and libstdc++.so.2.0 in /usr/lib.
LD_LIBRARY_PATH is set to /usr/local/rvplayer.

% ldd a.out
a.out:
/usr/libexec/ld.so: warning: libstdc++.so.2.0: minor version >= 1 expected, using it anyway
        -lg++.4 => /usr/lib/libg++.so.4.0 (0x4004b000)
        -lstdc++.0 => /usr/lib/libstdc++.so.2.0 (0x4007f000)
        -lm.0 => /usr/lib/libm.so.0.1 (0x400bc000)
        -lc.12 => /usr/lib/libc.so.12.31 (0x400d5000)
        -lcurses.2 => /usr/lib/libcurses.so.2.2 (0x40141000)
% unsetenv LD_LIBRARY_PATH
% ldd a.out
a.out:
        -lg++.4 => /usr/lib/libg++.so.4.0 (0x4004b000)
        -lstdc++.0 => /usr/lib/libstdc++.so.0.1 (0x4007f000)
        -lm.0 => /usr/lib/libm.so.0.1 (0x400bc000)
        -lc.12 => /usr/lib/libc.so.12.31 (0x400d5000)
        -lcurses.2 => /usr/lib/libcurses.so.2.2 (0x40141000)
>Fix:
	Perhaps this? Although it still doesn't quite seem right... I
don't know what's supposed to happen when different versions of a
library are in different directories though. I think the highest minor
version (with correct major version) out of all of the directories
should win. This patch makes it get the highest minor version in the
first directory it finds the library in.

--- /usr/src/gnu/usr.bin/ld/common/shlib.c	Sun Sep  6 06:07:22 1998
+++ shlib.c	Thu Sep 10 23:51:12 1998
@@ -249,14 +249,14 @@
 		DIR		*dd = opendir(search_dirs[i]);
 		struct dirent	*dp;
 		int		found_dot_a = 0;
-		int		might_take_it;
+		int		found_lib = 0;
 
 		if (dd == NULL)
 			continue;
 
-		might_take_it = 0;
 		while ((dp = readdir(dd)) != NULL) {
 			int	n;
+			int	might_take_it = 0;
 
 			if (do_dot_a && path == NULL &&
 					dp->d_namlen == len + 2 &&
@@ -310,10 +310,11 @@
 			ndewey = n;
 			*majorp = dewey[0];
 			*minorp = dewey[1];
+			found_lib = 1;
 		}
 		closedir(dd);
 
-		if (found_dot_a || might_take_it)
+		if (found_dot_a || found_lib)
 			/*
 			 * There's a lib in this dir; take it.
 			 */
>Audit-Trail:
>Unformatted: