Skip to content
rofl0r edited this page Sep 21, 2016 · 8 revisions

sabotage (in this incarnation) strives to achieve the following goals:

  • testbench for musl libc
  • usable as a chroot/rootfs-builder or full-blown distro
  • complete desktop and/or server distro featuring the most useful applications
    • minimal base environment: build only stage1 for a minimal set of dependencies
    • then build the packages that float your bloat (or everything, "butch install world")
  • one language
    • we assume knowledge of the english language is needed anyway to exploit the capabilities of a linux system in a creative way
    • language specific files, of which 99% are either unused or horrible translations, end up in binaries and directories.
    • remove Makefile targets generating them (often --disable-nls is sufficient)
    • provide stub version of gettext (gettext-tiny) to keep configure scripts happy.
  • minimal bloat
    • avoid resource-hungry C++, python, perl programs when possible
      • base system is completely C++ free, at least
    • remove dependencies
      • build kernel without perl (thanks to landley's patch series)
      • replace CMAKE horror with Makefile when feasible
      • etc
    • replace bloated libraries and programs with robust and light-weight solutions
      • glibc -> musl
      • coreutils, gnu sed, *utils -> busybox
      • pkg-config -> pkgconf
      • gettext -> gettext-tiny
      • udev -> busybox mdev
      • netlink -> nl-tiny
      • ncurses -> netbsd-curses
      • zlib -> sortix libz
      • [TODO] alsa-lib -> tinyalsa (tinyalsa has a too limited feature set)
      • readline -> libedit [TODO: incomplete, only works for gdb and mysql so far]
  • minimal compilation times
    • possibility for parallel builds
    • parallel downloads and builds, do not stop the whole world to wait for a download to finish
    • hand configure scripts a cache file with pre-defined answers, instead of checking for the same things over and over again
    • disable as much of gnulib/libiberty as possible
    • if necessary, replace the package's build system in favor of a simple makefile
    • gettext invocation is not free, copying dozends of .mo/.po files around neither, so
    • support only one language, english
    • disable tests, examples and the likes
  • multi platform
    • tested and built on all platforms musl libc supports, for which existing system-images can be found (currently all musl-supported archs except microblaze).
  • statically linked when it makes sense
    • for smaller or crucial core packages (busybox, gcc, gdb, strace, ...), static linking is used.
    • for stuff depending on a ton of libraries, or huge bloated libraries like openssl, dynamical linking is used to avoid memory waste.
  • offline usability
    • once you have done "butch prefetch [list of your favorite packages here]", or built sabotage once (which implies the above download of all source tarballs), everything needed to build, modify and use an entire linux distro is right there on your hd, even when the internet is unavailable for months or years. you should be able to use those tarballs together with the buildscripts on any computer device you're likely to find anywhere and compile sabotage linux for that device.
    • thus we must avoid build scripts that do not use release tarballs but download additional stuff from the internet (i.e. vim's 800 patches, or git/svn checkouts)
  • minimal startup overhead and complexity
    • instead of starting a gazillion of services and making the system so slow that we neeed a horribly bloated but parallel init process (systemd) to get it fast again, we just don't need/start them. busybox' init is used, you can add services via /etc/rc.local.
    • does anyone need runlevels in 2013 ?
    • no.
    • system boots in 2 seconds from bios to login prompt (qemu).
    • it's quite easy to understand what happens from kernel boot to login prompt.
  • user-friendly filesystem layout
    • no separation between /usr and /. there's only /. (i.e. /bin, /lib, /share, ...) to avoid problems with hardcoded /usr everywhere, usr is a symlink to /. (just think #!/usr/bin/env, and all kinds of broken build systems)
    • each package resides in its own dir (inspired by stow and gobolinux)
      • uses DESTDIR to install into /opt/packagename
      • symlinks from /opt/packagename to /
      • that way one can remove a package by simply deleting a directory.
      • you can copy a directory to another sabotage installation, use relocate.sh and everything's properly installed; if linked statically even including dependencies
      • makes it easy to find where a file comes from, or which files a package depends on
      • filelists are automatically generated
  • do not adopt the latest poettering/freedesktop/red hat BS
    • base gui apps on gtk+2 instead of gtk+3
      • unfortunately that means a few packages are not very up-to-date, and must be forked if they should be extended. a notable example is gnumeric.
    • no dbus dependency!
    • no systemd, no pulseaudio, no *kit
  • security
    • no suid binaries (FIXME: currently Xfbdev needs suid-root)
    • core packages are statically built, this removes all dynamic linking attack vectors
    • strong blowfish password hashes
    • grsecurity patched kernel (optional)
    • FIXME: the filesystem has not been audited yet, at this point it is likely that some permission vulns exist.
    • FIXME: packages are not always up-to-date and including the latest security fixes due to lack of developer resources.