Skip to content

Emulates privileged syscalls such as chroot(2) for unprivileged processes in userspace.

License

Notifications You must be signed in to change notification settings

gportay/iamroot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iamroot

Packaging status CodeQL Codacy Badge Codacy Badge FreeBSD-vm OpenBSD-vm NetBSD-vm

iamroot(7) emulates privileged syscalls such as chroot(2) for unprivileged processes in userspace.

TL;DR;

iamroot(7) works towards creating rootfs from the binary packages of the most popular Linux distributions without the need for sudo(8).

The project is a self-contained and all-in-one alternative to fakeroot(1) and fakechroot(1). It gives unprivileged user permissions to call privileged syscalls such as chown(2) and chroot(2) by emulating them.

iamroot(7) targets the Linux userlands glibc and musl. It works on FreeBSD, OpenBSD and NetBSD even if its usage is limited by various statically linked binaries and by non-executable dynamic loaders.

The project compiles on Intel x86 and ARM 64-bit, and it runs on Arch Linux, Debian, Alpine Linux, FreeBSD, OpenBSD and NetBSD.

The Miscellaneous Binary Format on Linux allows to chroot(2) in a rootfs directory using a different architecture thanks to emulators (such as the QEMU user-mode emulation static binaries). The architectures x86_64, i386, aarch64, aarch64_be, armhf, arm, riscv64, mipsle mips64le, powerpc64, powerpc64le, powerpc and s390x are supported.

HOW IT WORKS

PRELOAD

It consists of an ELF shim library which is preloaded using the environment variable LD_PRELOAD.

It intercepts the calls to the libc functions requiring privileged syscalls or having a filename or pathname in parameter. Some functions re-implement the functionality, somes are simple stubs returning success.

ROOT DIRECTORY

The syscall chroot(2) changes a small ingredient in the pathname resolution process; it is visible via each process's symlink /proc/self/root. The environment variable IAMROOT_ROOT implements that behaviour in the world of iamroot(7). Basically, it replaces the leading / of an absolute pathname with the alternate root directory path.

MAGIC

For the curious, the magic operates in files chroot.c for entering in chroot, in chdir.c and fchdir.c for exiting "chroot jail", in path_resolution.c for resolving pathnames, and in execve.c and dso.c for exec'ing executable files from chroot by rewriting the whole command-line using the dynamic loader and it's options (i.e. --preload, --library-path and --argv0 if they exist).

PERMISSION DENIED

Of course, iamroot(7) cannot substitute itself to the superuser permissions, and commands will end with EACCESS or EPERM as of reading or writing files in /proc, /sys, /dev or /run.

HELPER SCRIPTS

iamroot(7) is configurable via environment variables to overcome specific situations of the whole variety of operation-systems (i.e. GNU/Linux, musl, *BSD...).

It comes with two shell scripts to make the configuration easy via specific command line options. They are frontends to standard CLIs to either open an interactive shell or to switch user. ish(1) provides a shell like sh(1), and ido(1) switches user like sudo(8).

BUILD ROOTFS

iamroot(7) aims to create any Linux rootfs using the package manager of the distribution (or its bootstrap script).

The table below lists the distributions and its tool that work with.

Tool Distributions
pacstrap(8) Arch Linux, Arch Linux ARM, Arch Linux 32, Arch Linux RISC-V, Arch POWER, Manjaro
alpine-make-rootfs Alpine Linux, Adélie Linux
dnf(8) Fedora
zypper(8) openSUSE
debootstrap(8) Debian, Ubuntu*, Devuan
mmdebstrap(1) Mobian
xbps-install(1) Void Linux

*: Works with hacks.

GLIBC

The GNU C Library leaks symbols in the dynamically linked binaries and shared libraries.

As a consequence, the binaries or the shared libraries need to run along with the same or any later version of the glibc.

For this reason, the iamroot(7) library is NOT linked against the default libraries by the dynamic linker at link-time.

Instead, the libraries libc.so.6, libdl.so.2, libpthread.so.0 and libgcc_s.so.1 are patchelf'ed manually afterward.

This works around the missing symbols raised by the dynamic loader at run-time.

However, it does not solve for the missing symbols leaked in the binaries and shared libraries loaded from within the chroot(2)-ed directory.

The symbols must be implemented in the iamroot(7) library or loaded from a third-party library (such as the gcompat library which runs glibc-binaries from a musl-system).

FAKECHROOT

fakechroot(1) is perfectible to create rootfs. There are several issues to address to make a rootfs.

fakechroot(1) does not strip de chroot directory in the absolute symlink targets and, consequently, leaks the chroot directory in the alternate rootfs. Either, it does not resolves and follows the symlinks correctly.

dnf(8) enters and exits the "chroot jail" to run the packages scriptlets but fakechroot(1) does not support exiting if chdir(2)'ing out of the chroot directory. Moreover, the function fchdir(2) is not intercepted.

Besides, the GNU C Library leaks symbols in the dynamically linked binaries. Therefore, the binaries MUST load the same or any later version of the libc. fakechroot(1) runs the host wide dynamic loader, hence, it cannot run binaries or load libraries linked against newer version of glibc with extra new symbols; even setting the environment variable FAKECHROOT_ELFLOADER or using the option --use-system-libs. And this includes the library libfakechroot.so itself.

It is even worse if considering running binaries for another architecture, as the appropriate dynamic loader MUST get installed on the host system to get run by the kernel. Additionnaly, the library libfakechroot.so MUST get installed alongside the rootfs. However, fakechroot(1) does not compile in a musl world.

fakechroot(1) blindly trusts the environment variable LD_PRELOAD is set and preserved across the processes, although, dracut(8) unset the dynamic loader environment variables and it shoots itself in the foot.

For all those latter reasons and since the Linux ld.so(8) can execute binaries, then iamroot(7) rewrites the whole command line to overcome all the limitations mentioned above.

PSEUDO

pseudo(1) is another alternative to both fakeroot(1) and fakechroot(1). It is used by The Yocto Project.

It appears pseudo(1) is compiled and linked against the host libc, accordingly, pseudo(1) would fail to chroot(2) and run a binary linked against former versions of glibc with missing new symbols.

DOCUMENTATION

Build the documentation using make(1)

$ make doc
asciidoctor -b manpage -o ido.1 ido.1.adoc
gzip -c ido.1 >ido.1.gz
asciidoctor -b manpage -o ish.1 ish.1.adoc
gzip -c ish.1 >ish.1.gz
asciidoctor -b manpage -o iamroot.7 iamroot.7.adoc
gzip -c iamroot.7 >iamroot.7.gz
asciidoctor -b manpage -o ld-iamroot.so.8 ld-iamroot.so.8.adoc
gzip -c ld-iamroot.so.8 >ld-iamroot.so.8.gz
rm iamroot.7 ish.1 ido.1 ld-iamroot.so.8

BUILD

Run the following command to build ld-iamroot.so and libiamroot.so

For your home directory (i.e. your user only)

$ make ld-iamroot.so libiamroot.so PREFIX=$HOME/.local

Or, for your system (i.e. every users)

$ make ld-iamroot.so libiamroot.so

INSTALL

Run the following command to install iamroot(7), ido(1) and ish(1)

To your home directory (i.e. your user only)

$ make user-install

Or, to your system (i.e. every users)

$ sudo make install

The traditional variables DESTDIR and PREFIX can be overridden

$ sudo make install PREFIX=/opt/iamroot

Or

$ make install DESTDIR=$PWD/pkg PREFIX=/usr

BUGS

Report bugs at https://github.com/gportay/iamroot/issues

AUTHOR

Written by Gaël PORTAY [email protected]

COPYRIGHT

Copyright (c) 2021-2024 Gaël PORTAY

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version.

SEE ALSO

iamroot(7), ido(1), ish(1), ld-iamroot.so(8), chroot(2), path_resolution(7), fakechroot(1), fakeroot(1), pseudo(1), binfmt_misc, qemu

About

Emulates privileged syscalls such as chroot(2) for unprivileged processes in userspace.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published