Hi all,
I don't know if this is the right place, but I think the loader shlud be part of the kernel.
I discovered that the latest loader ld-2.6.1 acts in a different way compared to the previous ones (the one I'm compared with is ld-2.3.4).
The dynamic libraries are loaded at pseudo-random memory addresses, whilst before they were loaded always starting at the same address.
This unfortunately is a big problem for our software, because we used to save in a memory mapped file objects referencing to virtual functions.
Anyone of you can help me ?
Thanks in advance
Gian Piero Izzo
this is a kernel feature :)
mmap() (and therefore library) and stack address randomization is a security feature of the kernel: the constant addresses you need are beneficial for exploit code, too. this feature is only enabled for executables that are linked with known good (new enough) libc versions or binutils and that are not marked to be incompatible with this randomization. i don't know how to set this mark, you will have to find out.
apart from this the mapping address of a shared library is never guaranteed (what do you do if you update a library and the new code needs more space?), it is bad style to write fixed memory pointers into a file and not be able to relocate the addresses. you could keep track of your pointers and relocate them yourself (add the difference between old and new address) or do the same as standard ELF dynamic linking, which is position independent: all inter-module accesses are indirect via the global offset table (GOT) for data and the procedure linkage table (PLT) for code. i.e. your code does not use a pointer p and access *p, but it uses the index i into pointer table pt and accesses *pt[i]: this way you only have to update the pointers in the pointer table and you can have a different pointer table per process mmap()ing your file.
Thank you very much for your
Thank you very much for your reply.
I know that this way to proceed is not so good, but we are using an old permanent object storage utilit (POST++) and for performance reasons the relocation of all objects would take too much time.
Practically an application (Importer) takes care to instantiate thousands of standard C++ objects using a memory mapped file. All other applications can then directly use all instantiated objects (we call it runtime database) directly memory mapping the file. The problem is that this objects contain references to virtual functions which then need to be correctly placed in memory.
Now the worst part is that I can't rebuild the software, because there are libraries provided by ILOG (Views 5.0.1) which need stdlib.co.5, so no way.
Is there no possibility to ask the loader wo work in some backward compatibility mode ?
Thanks again
Gian Piero
/proc/sys/kernel/randomize_va_space
hopefully this sysctl: /proc/sys/kernel/randomize_va_space will help you
from : Documentation/sysctl/kernel.txt
randomize-va-space:
This option can be used to select the type of process address
space randomization that is used in the system, for architectures
that support this feature.
0 - Turn the process address space randomization off by default.
1 - Make the addresses of mmap base, stack and VDSO page randomized.
This, among other things, implies that shared libraries will be
loaded to random addresses. Also for PIE-linked binaries, the location
of code start is randomized.
With heap randomization, the situation is a little bit more
complicated.
There a few legacy applications out there (such as some ancient
versions of libc.so.5 from 1996) that assume that brk area starts
just after the end of the code+bss. These applications break when
start of the brk area is randomized. There are however no known
non-legacy applications that would be broken this way, so for most
systems it is safe to choose full randomization. However there is
a CONFIG_COMPAT_BRK option for systems with ancient and/or broken
binaries, that makes heap non-randomized, but keeps all other
parts of process address space randomized if randomize_va_space
sysctl is turned on.
-Patrick
--
http://www.ducksong.com/
http://bitsup.blogspot.com/
Everything works !
Thank you so much,
I changed the kernel parameter back to 0 and now everything works perfectly! You saved me a lot of work, I owe you a beer :-)
Regards
Gian Piero
note of thanks
"fixing stack location in linux loader"
Just want to take the time to say "thanks" for you
taking the time to inform about the linux kernel.
I found the randomize_va_space tip perfectly useful.
My altavista search is above, and it was the one
that got me to the solution in this thread All who answer
questions deserve lauds. I myself contribute, too.
My purpose was security and hostile process analysis.
Yeah, I'll buy you a virtual beer, too! ;-)
hmm
VDSO is still not very useful, at least if local stack overflow exploits are concerned, there are some problems with it like:
ffffe000-fffff000 ---p 00000000 00:00 0 [vdso]
The virtual "vdso" shared object is always loaded at this address, 0xffffe000
Futhermore, looking with gdb at the memory around that location, we see:
(gdb) x/1000 0xffffe000
...
0xffffe080: 0xffffe460 0x00000018 0x00000018 0x00000004
...
FF E4 is the x86 opcode for "jump to stack pointer (jmp ESP)"
So imagine you overflow the stack, all you need to overwrite the return address(saved EIP) with the address of that "jmp esp" instruction, which is located at a static (non-randomized address).
Voila, we jumped right onto the stack, overwritten with our evil code.
Of course, that's kinda simplified and things are trickier in real life, but the concept is valid.
Things would get different if non-executable stack patch is applied, but that's another story :)