Valery Reznic wrote:
P.S. And what do you need it for (except curiosity) ?
It's going to be a somewhat long p.s. If you understood the problem I'm
trying to solve, skip ahead to area marked "proposed solution" for how
I'll be trying to solve it.
Here's a piece of trivia for you. /lib/ld-linux.so and glibc go
together. This is true in the sense that they are compiled from the same
sources, but even more so, it is true in the sense that you cannot
intermix versions of it. Take an old linux version's chroot you have,
replace ld-linux there with a new version, and try chrooting into it.
You will likely get something along the lines of the following error:
# /usr/sbin/chroot /srv/chroot/etch/
/bin/bash: relocation error: /lib/tls/libc.so.6: symbol
_dl_out_of_memory, version GLIBC_PRIVATE not defined in file
ld-linux.so.2 with link time reference
I'm not sure whether it's glibc relying on ld-linux or the other way
around (the first would, at least, make some kind of sense), but any way
you turn it, things don't work.
As far as I know, there are three approaches to emulating a chroot.
There is "fakechroot", which uses LD_PRELOAD. This means it cannot
override anything that ld-linux (a statically compiled library, for
obvious reasons) do, which means that when you run "chroot
/srv/chroot/etch/", both ld-linux and glibc (as well as any other
library mentioned in the ELF header) gets loaded from the real root of
the system, so no problem there (except the obvious one - that the
chroot isn't much of one). The second approach is the one employed by
user mode linux. It basically catches everything and everywhere, and
replaces the entire tasks otherwise performed by the real kernel, and so
no problem but a HUGE overhead.
Fakeroot-ng goes the middle path. In concept it does what fakechroot
does - intercept syscalls and either perform them differently, give
bogus answers or emulate something. The main difference (well, the main
core difference) is that fakeroot-ng uses ptrace rather than LD_PRELOAD,
which means that statically compiled programs (as well as programs
merely not linked with glibc, or linked with a different version etc..)
are handled. There is just one problem: Since that is the case, when you
run "chroot /srv/chroots/etch", you get a chrooted process (i.e. - a
process that fakeroot-ng emulates all path calls for) that tries to load
/lib/glibc (which fakeroot-ng redirects to /srv/chroots/etch/lib/glibc).
The entity loading the interpreter, however, is the kernel, and that is
not controlled by fakeroot-ng. The result is that the Etch glibc is run
with Lenny's ld-linux, and you get the same error message as above.
The proposed solution
I can't say I have it firmly, or that I know it will work. This is just
something I'm investigating. The idea is that we modify the execve
syscall so that instead of running /bin/cat or
/srv/chroots/etch/bin/cat, we run /srv/chroots/etch/lib/ld-linux.so.
This will cause the kernel to set up the memory and process state in a
way that is almost what we want to eventually happen. After a successful
execve on a traced program, the debugger gets a signal with the program
traced before it had a chance to execute a single instruction. We then
manually load /srv/chroots/etch/bin/cat into the process state, and
modify the runtime structures so that ld-linux will think it was started
in interpreter mode rather than in direct mode. This will cause the
right interpreter to be loaded, and everything should work.
There are many steps to climb in this plan, of course, but the only one
for which I was missing data was this - where ld-linux found out which
interpreter is active, and what other data is in there that maybe needs
to be processed. For example, I found out that auxv also stores the uid
and euid, and I may wish to modify these (as I'm trying to fool the
program into thinking it's running as root). Then again, things worked
fine so far without it, and I only need to delve there if I'm doing a
chroot, so I may not bother. We'll see.
Hope that answered the curiosity part :-)
Shachar
=================================================================
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]