- Subject: libc/1447: malloc fails if the executable is called via /lib/ld-2.1.1.so ./testexec
- From: schwidefsky at de dot ibm dot com
- Date: Sun Nov 14 19:25:56 1999
Topics:
libc/1447: malloc fails if the executable is called via /lib/ld-2.1.1.so ./testexec
----------------------------------------------------------------------
Date: Fri, 12 Nov 1999 08:50:12 -0500
From: schwidefsky@de.ibm.com
To: bugs@gnu.org
Subject: libc/1447: malloc fails if the executable is called via /lib/ld-2.1.1.so ./testexec
Message-Id: <199911121350.IAA00198@delysid.gnu.org>
>Number: 1447
>Category: libc
>Synopsis: malloc fails if the executable is called via /lib/ld-2.1.1.so ./testexec
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: libc-gnats
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Fri Nov 12 09:00:01 EST 1999
>Last-Modified:
>Originator: schwidefsky@de.ibm.com
>Organization:
net
>Release: glibc 2.1.2
>Environment:
Linux 2.2.10, glibc-2.1.1, egcs-2.91.66
>Description:
The first time I encountered the problem was trying to compile glibc-2.1.2.
rpcgen and zic died with a segmentation fault in the make process of glibc.
The following little programs shows the same problem:
- -- cut here ---
#include <stdio.h>
#include <malloc.h>
int main(void) {
char *p = malloc(65536);
printf("Malloc returned %x\n", p);
return 0;
}
- -- cut here ---
If the test its executed directly there is no problem:
Output:
Malloc returned 80495a8
Strace log:
execve("./testldso", ["./testldso"], [/* 22 vars */]) = 0
brk(0) = 0x80495a0
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=0, st_size=0, ...}) = 0
mmap(0, 15894, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aabf000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
fstat(3, {st_mode=031266, st_size=0, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
mmap(0, 974392, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x2aac3000
mprotect(0x2aba9000, 32312, PROT_NONE) = 0
mmap(0x2aba9000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xe5000) = 0x2aba9000
mmap(0x2abae000, 11832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2abae000
close(3) = 0
munmap(0x2aabf000, 15894) = 0
personality(PER_LINUX) = 0
getpid() = 28626
brk(0) = 0x80495a0
brk(0x80595b8) = 0x80595b8
brk(0x805a000) = 0x805a000
fstat(1, {st_mode=S_IFREG|S_ISUID|06, st_size=0, ...}) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aabf000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "Malloc returned 80495a8\n", 24Malloc returned 80495a8) = 24
munmap(0x2aabf000, 4096) = 0
_exit(0) = ?
If the test its executed indirectly with "/lib/ld-2.1.1.so ./testldso"
the problem shows up (if it does not make the malloc chunk bigger):
Output:
Malloc returned 0
Strace log:
execve("/lib/ld-2.1.1.so", ["/lib/ld-2.1.1.so", "./testldso"], [/* 22 vars */]) = 0
getuid() = 509
getgid() = 505
geteuid() = 509
getegid() = 505
brk(0) = 0x2aabe368
brk(0x2aabf368) = 0x2aabf368
open("./testldso", O_RDONLY) = 3
fstat(3, {st_mode=S_IFDIR|S_ISGID|016, st_size=0, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2"..., 4096) = 4096
connect(715908680, ptrace: umoven: Input/output error
{...}, 715907148) = 23
mmap(0x8048000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x8048000
mmap(0x8049000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x8049000
close(3) = 0
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=0, st_size=0, ...}) = 0
mmap(0, 15894, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aac0000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
fstat(3, {st_mode=031266, st_size=0, ...}) = 0
fstat(3, {st_mode=031266, st_size=0, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
mmap(0, 974392, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x2aac4000
mprotect(0x2abaa000, 32312, PROT_NONE) = 0
mmap(0x2abaa000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xe5000) = 0x2abaa000
mmap(0x2abaf000, 11832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2abaf000
close(3) = 0
munmap(0x2aac0000, 15894) = 0
personality(PER_LINUX) = 0
getpid() = 28638
brk(0) = 0x2aabf368
brk(0x2aacf380) = 0x2aabf368
fstat(1, {st_mode=S_IFREG|S_ISUID|06, st_size=0, ...}) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aac0000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "Malloc returned 0\n", 18Malloc returned 0) = 18
munmap(0x2aac0000, 4096) = 0
_exit(0) = ?
The reason for that the current->mm->brk value of the process. For the direct
call it points to the end of testldso (brk(0) = 0x80495a0). For the indirect
call it points to the end of the dynamic linker (brk(0) = 0x2aabf368). After
the dynamic linker the libc-2.1.1.so is loaded so there is not much room after
ld-2.1.so image in memory. The try to enlarge the memory by another 64K
(brk(0x2aacf380) = 0x2aabf368) fails and malloc returns 0.
>How-To-Repeat:
>Fix:
>Audit-Trail:
>Unformatted:
------------------------------
End of forwardRIAV_G Digest
***************************