[Haifux] Announcing a new project - fakeroot-ng
Shachar Shemesh
shachar at shemesh.biz
Sun Dec 30 19:28:21 MSK 2007
Hi all,
I would like to intrude upon your time to announce an EXTREMELY
preliminary project called "fakeroot-ng". Project web site is at
http://sourceforge.net/projects/fakerootng. At this point there is no
formal release, but you can get the code from SVN and it compiles fine
on Linux i386 (yes, it requires per-platform support). I'm hoping to
release an actual release by the end of this week.
The project is a clean reimplementation of fakeroot[1]. For those who
don't know it, fakeroot uses LD_PRELOAD in order to wrap some system
calls and fool the process into thinking it is running as root. Fakeroot
further keeps tabs on the operations it is impossible for the process to
perform, but was told it succeeded anyways, and will emulate the results
when applicable. So, for example, if you use fakeroot to create a
character device (which only root can), and then run "ls -l", you will
see your character device. In actuality, it's a standard file, but
fakeroot fools the process to think it's a character device.
Fakeroot has one major limitation, though. It does not, and cannot,
support a chroot jail. Fakeroot's authors refuse to wrap the "open"
system call, due to implicit recursion that it results in, which turn
into a infinite loop. A different implementation, called "fakechroot",
exists that does wrap "open" and does support chroot. According to the
fakeroot authors, this implementation is highly dependent on the precise
implementation inside glibc. Either way, the technology still dictates
several limitations, as listed on the fakechroot web site [2].
Fakeroot-ng, which stands for fakeroot next generation, uses a whole
different technology to wrap the system calls. Instead of using
LD_PRELOAD, it uses ptrace to debug the process being fooled. As a
result, it has no problem with statically linked binaries, binaries
written in Java, or binaries linked with a different version of glibc.
In fact, it is written in C++ without affecting the process' dynamic
linking structure.
Of course, with the good cometh the bad. In particular, ptrace is highly
platform dependent in every way imaginable. Also, since we are
manipulating the process data structures from without, we do not have
any memory to call our own with which to work. This is particularly
painful where supporting one syscall requires actually performing two or
more.
For example, we want to intercept the "fchmod" function, so we can
update our internal data about SUID and similar bits (which we don't
want to allow in the real file). Since the primary key to our database
is the tuple <dev,inode>, and since "fchmod" contains none, we need to
carry out the actual fchmod, but also call "fstat" in order to know what
the device and inode numbers are. We need to turn one system call into
two. Unfortunately, ptrace has no mechanism for generating a system call.
Fakeroot-ng solves this problem. Furthermore, it solves this problem in
a way that requires very little #ifdef blocks (anyone who tried to read
the strace source code has got to appreciate this fact).
How? Invite me to lecture at one of the Linux clubs and I'll tell you.
Better yet, download the source code and look for yourself. Even better,
send me patches to add support for more platforms.
Here is a demo of fakeroot-ng in action:
dir$ ls -la
> total 8
> drwxr-xr-x 2 sun sun 4096 2007-12-30 17:48 .
> drwxr-xr-x 7 sun sun 4096 2007-12-30 17:48 ..
> dir$ touch file
> dir$ ls -la
> total 8
> drwxr-xr-x 2 sun sun 4096 2007-12-30 17:48 .
> drwxr-xr-x 7 sun sun 4096 2007-12-30 17:48 ..
> -rw-r--r-- 1 sun sun 0 2007-12-30 17:48 file
> dir$ ../fakeroot-ng sh
> sh-3.1# ls -la
> total 8
> drwxr-xr-x 2 sun sun 4096 2007-12-30 17:48 .
> drwxr-xr-x 7 sun sun 4096 2007-12-30 17:48 ..
> -rw-r--r-- 1 sun sun 0 2007-12-30 17:48 file
> sh-3.1# whoami
> root
> sh-3.1# id
> uid=0(root) gid=1000(sun)
> groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),107(netdev),110(powerdev),1000(sun),1001(vboxusers)
> sh-3.1# chmod 4775 file
> sh-3.1# ls -la
> total 8
> drwxr-xr-x 2 sun sun 4096 2007-12-30 17:48 .
> drwxr-xr-x 7 sun sun 4096 2007-12-30 17:48 ..
> -rwsrwxr-x 1 sun sun 0 2007-12-30 17:48 file
> sh-3.1# exit
> exit
> dir$ ls -la
> total 8
> drwxr-xr-x 2 sun sun 4096 2007-12-30 17:48 .
> drwxr-xr-x 7 sun sun 4096 2007-12-30 17:48 ..
> -rwxrwxr-x 1 sun sun 0 2007-12-30 17:48 file
Notice how "file" has the SUID bit set when inside the fakeroot environment, but not when you exit it.
comments and suggestions welcome on the fakeroot-ng mailing list [3]
Share and enjoy
Shachar
[1] http://fakeroot.alioth.debian.org/
[2] http://fakechroot.alioth.debian.org/
[3] http://sourceforge.net/mailarchive/forum.php?forum_name=fakerootng-devel
More information about the Haifux
mailing list