Bug 640154 - ldd regression
Summary: ldd regression
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 14
Hardware: All
OS: Linux
low
medium
Target Milestone: ---
Assignee: Andreas Schwab
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-10-05 02:59 UTC by Alberto Bertogli
Modified: 2016-11-24 15:38 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2010-10-05 07:52:09 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Alberto Bertogli 2010-10-05 02:59:26 UTC
Hi!

I installed F14B on a 64-bit VM (kvm) to give it a try, and see if some
projects worked fine on it.

One didn't, and while debugging the issue, I found what I believe is a
regression in ldd. That is, it used to work on F13, but now it doesn't.

The issue is very easy to reproduce, just run:

        ld -o libccheck.so -lc -shared

to create an "empty" shared library linked with libc, and then:

        ldd libccheck.so


This is what fails, but used to work. It says "not a dynamic
executable", and I expected it to emit the normal library dependency
list.

This same experiment works on Debian testing and Ubuntu 10.04.

I also copied the .so built in F14B to an Ubuntu install and ran ldd on
it. It worked as expected, so it is likely that this is an ldd issue and
not an ld one.

Following a suggestion in the devel mailing list, I verified that the ld
in use was ld.bfd. The initial "empty" linking fails with ld.gold (it
complains about -lc).

Let me know if you need any additional information. If there is anything
you want me to do, test or debug, I'd be glad to.

Thanks a lot,
		Alberto

Comment 1 Alberto Bertogli 2010-10-05 05:32:26 UTC
After digging a bit more into this, I think I found more relevant information.

ldd tries to use /lib/ld-linux.so.2 first, and then
/lib64/ld-linux-x86-64.so.2, to verify the given .so is in fact a dynamically
linked library. At least that's what I could read from ldd's code, and
ld-linux's manpage.

In Debian/Ubuntu, where it works, I can do this:

	$ /lib64/ld-linux-x86-64.so.2 --verify ./libccheck.so ; echo $?
	2

That 2 is taken by ldd as a valid verification.

However, on F14, it outputs 1, which means it is an invalid object.


If I run the trace request manually, I get this on a working system:

	$ LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 ./libccheck.so
		linux-vdso.so.1 =>  (0x00007fff10a78000)
		libc.so.6 => /lib/libc.so.6 (0x00007fae07d8b000)
		/lib64/ld-linux-x86-64.so.2 (0x00007fae08335000)

but this on F14:

	# LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 ./libccheck.so
	./libccheck.so: error while loading shared libraries: ./libccheck.so:
		cannot enable executable stack as shared object requires:
		Permission denied

That sounds suspicious, because I'm running it as root, and

	# ls -lsa libccheck.so 
	4 -rwxr-xr-x. 1 root root 1592 Oct  4 15:02 libccheck.so


Another interesting (but likely unrelated) thing I found is the following:

# strace /lib64/ld-linux-x86-64.so.2 --verify libccheck.so 
execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2",
	"--verify", "libccheck.so"], [/* 27 vars */]) = 0
brk(0)                                  = 0x7f787a970000
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=18671, ...}) = 0
mmap(NULL, 18671, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f787a007000
close(3)                                = 0
exit_group(1)                           = ?

Note how it does not even _try_ to open libccheck.so.

However, if I run it like this, it does:

# strace /lib64/ld-linux-x86-64.so.2 --verify ./libccheck.so
execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2",
	"--verify", "./libccheck.so"], [/* 27 vars */]) = 0
brk(0)                                  = 0x7f73fd966000
open("./libccheck.so", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"...,
	832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1592, ...}) = 0
getcwd("/root", 128)                    = 6
mmap(NULL, 2097776, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0)
	= 0x7f73fc664000
mprotect(0x7f73fc665000, 2093056, PROT_NONE) = 0
mmap(0x7f73fc864000, 4096,
	PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0)
	= 0x7f73fc864000
mprotect(0x7fffb2cb7000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN)
	= -1 EACCES (Permission denied)
close(3)                                = 0
exit_group(1)                           = ?

This behaviour appears both in working and non-working systems.

Is this because without "./" it tries to find the library in ld.so.conf and
fails?

Thanks,
		Alberto

Comment 2 Andreas Schwab 2010-10-05 07:52:09 UTC
You need to tell the linker that you need no executable stack or disable selinux.

Comment 3 Alberto Bertogli 2010-10-06 02:27:19 UTC
That's good to know.

In case it matters, I confirm that it worked that way.

Thanks a lot,
		Alberto


Note You need to log in before you can comment on or make changes to this bug.