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]

Reply via email to