Valery Reznic wrote:

I think your proposed solution will work (no reason why not)
Actually, I can think of four or five reasons why it may fail, but I'll cross those bridges when I get to them.
And if you change AT_ENTRY in the auxv you'll trick ld-linux to think
it was loaded as interpreter and not directly.
But why you need it and what good it will do ?
It will allow me to control both which executable is loaded AND which interpreter, thus allowing me to emulate the chroot syscall, adding another small functionality to what fakeroot-ng can do. I'm not sure this program passes the investment/return tradeoff, but it's fun to do stuff no one was insane enough to do before, so I go ahead anyways.
Interpreter use this information (interpreter/directly) to adjust argc/argv that will be passed to main()
Except the argv array passed is the one for interpreter mode, not direct mode.

You app does:
chroot("/srv/chroots/etch")
chdir("/");
execve("/bin/bash", array("-bash", NULL))

You would expect to get a login shell, whose "ps" show up as being called "-bash" (what makes it a login shell), chrooted.

If you just run your program, chroot will return EPERM because you are not root.

If you run it using fakechroot, you will get the chroot version of bash, but using the real root's glibc, ld-linux, curses and whatever else bash uses.

When you run it with fakeroot-ng, this is what happens today:
chroot - the call is intercepted, and turned into a "geteuid" (or, in other words, a NOP). Fakeroot resolves /srv/chroots/etch, and marks that as the new root for your process. chdir - fakeroot-ng intercepts that, and resolves "/" to mean "/srv/chroots/etch/", it lets the original chroot continue using the altered argument. excve - fakeroot-ng intercepts that, and turns "/bin/bash" into "/srv/chroots/etch/bin/bash". execve continues, load /lib/ld-linux.so.2 to handle the dynamic linking, which call open on "/lib/libc.so.6". Fakeroot-ng intercepts that and turns it into an open on "/srv/chroots/etch/lib/libc.so.6". Since /lib/ld-linux.so.2 and /srv/chroots/etch/lib/libc.so.6 are of different versions, things break down.

What will happen:
execve - intercepted. Fakeroot-ng converts /bin/bash into /srv/chroots/etch/bin/bash, reads the file, sees it is ELF, checks the interpreter, sees that it is /lib/ld-linux.so.2, converts that to /srv/chroots/etch/lib/ld-linux.so.2, make some sanity checks, and alter the arguments. Now the syscall that actually goes into the kernel is:
execve("/srv/chroots/etch/lib/ld-linux.so.2", array("-bash", NULL))
As soon as the kernel finishes the setup, fakeroot-ng again takes control. It parses /srv/chroots/etch/bin/bash, and make the calls (somehow) in the process context to open that file, and map it into memory in the correct areas. It also patches auxv's entry points to be the correct ones for bash. It then allows the process to go on executing. ld-linux figures out it was loaded in interpreter mode, parses the bash ELF headers (which fakeroot-ng, rather than the kernel, placed in memory), and figures it needs to load /lib/libc.so.6. It calls open("/lib/libc.so.6") fakeroot-ng intercepts that call, and converts it to open("/srv/chroots/etch/lib/libc.so.6") Both interpreter and libc are loaded from the chroot environment, so everything works
????
profit

Valery
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