Lilblue Linux: release 20140218

I just pushed out a new release of Lilblue Linux 20140218 [1] which you can download from any Gentoo mirror [2].  For those of you who don’t know, Lilblue Linux is a security-enhanced fully featured XFCE4 desktop system for amd64.  It is built with Gentoo’s hardened toolchain [3] and uses Gentoo’s hardened-sources for the kernel which include the Grsec/PaX patches [4] for added security.  Lilblue Linux really is Gentoo, so the name is a bit pretentious, but there is one important and interesting twist: it is built using uClibc [5] as its standard C library rather than glibc, giving it some advantages of an embedded system, such as speed.

Release 20140218 is primarily a maintenance release in which I updated all the packages so as to sync up with maintream Gentoo’s stable amd64 set.  I didn’t touch the toolchain since there was no pressing need, but I did update the kernel to hardened-sources-3.12.6.  There were no known major security issue nor major bugs in the previous release.  But, there was a lot of package flux, with lots of fixes that resolved some annoying issues which plagued the earlier release.  One such annoyance was SMPlayer that used to open up a second window to play a video rather than rendering it in the main window.

If you are already running Lilblue, you can probably just do a `emerge –sync; layman -S; emerge -uvND world` and get caught up [6], but if you are starting a fresh system, the newer image cleans out those annoyances, so you want to start there.  One of the reasons I push out new images every few months is that there are always glitches when updating.  This is true of any Gentoo system but all the moreso of Lilblue because most software is developed under the assumption that we are building against glibc.  These assumptions (GNU-isms) manifest themselves in varioius ways: 1) assumptions about the availability of functions which are GNU extensions, such as secure_getenv() in systemd’s code base which eudev removes [7],  2) assumptions about header stacking, eg. using variadic functions without including stdarg.h (You can sometimes get away with this on a glibc system because it sneaks in via some other included header, but not in uClibc), [8] and 3) missing LDFLAGS like, -liconv -lintl or -largp, which are needed to find these breakout libraries [9].  There are, however, some very deep issue which require serious investigation, such as the removal of poll_waiting in glib (versions above 2.30.3) which lead to a dead lock for all applications linking against it.  It turned out that the issue there was in uClibc’s implementation of eventfd() [10].  Another interesting bug in uClibc-0.9.33.2 was the non-atomic implementation of pread() and pwrite() in terms of open() and lseek() [11].  This caused a race in git-1.8.x which does a multithreaded unpacking of the deltas and requires atomic pread/pwrite.  Mike Frysinger (vapier) had already worked out the implementation in terms of SYS_pread64/pwrite64 but these had not yet been backported.  The latest adventure was on arm architecture (yes I’m thinking of porting Lilblue to arm) where the syscall for pread/pwrite was being done using _syscall5() rather than _syscall6() and not properly aligning the 64-bit value on even register pairs.  This again broke pread/pwrite and git, but only on arm arch! [12]  Mike again had the fix and backported it.

Lilblue is built form a stage3-amd64-uclibc-hardened tarball that can be found on any gentoo mirror under /experimental/uclibc along side the Lilblue image itself [2].  I keep the build scripts on Gentoo’s releng (release engineering) git repo [13] and I run them occassionally to see if any major issues are creeping in as mainstream Gentoo evolves.  If everything goes well, then I don’t push out another release to avoid taxing the mirrors.  But when things get complicated, or a large number of packages need updating, I get the feeling I’d better push out another release.  I hope one day to have a binpkg system going where you can donwload a ~200MB seed image and then install from a binhost but this is more involved than I first suspected.

So give it a try in a virtual machine if you like.  It runs out-of-the-box on VirtualBox.  Installation instructions are on the home page [1].  Or run it as you main desktop as I do on one of my boxes at home!

References:

[1] https://wiki.gentoo.org/wiki/Project:Hardened_uClibc/Lilblue

[2] The image is named desktop-amd64-uclibc-hardened-[release].tar.bz2 and can be found at http://distfiles.gentoo.org/experimental/amd64/uclibc/

[3] https://wiki.gentoo.org/wiki/Hardened/Toolchain

[4] http://grsecurity.net/

[5] http://uclibc.org/

[6] While I’ve tried to get most of the fixes either into the main Gentoo tree, or upstream, some patches still remain and so I maintain a repository for them: http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-dev.git;a=shortlog;h=refs/heads/uclibc

[7] See man 3 getenv.  While getenv conforms to SVr4, POSIX.1-2001, 4.3BSD, C89 and C99, secure_getenv() is a GNU extension.

[8] The header stacking problem works both ways.  In https://bugs.gentoo.org/show_bug.cgi?id=497200, sys-apps/kbd failed to build on uClibc because of a missing stdarg.h when trying to prototype functions with variadic parameters.  Contrast this to https://bugs.gentoo.org/show_bug.cgi?id=486782, where app-cdr/cdrtools fails to build because including stdio.h indirectly includes bits/sched.h which defines clone() (as in man 2 clone).  But this clashes with a definition of clone() in cdrtools’ readcd.c.  Upstream felt that this was a poor implementation on the part of uClibc and the stacking problem there should be fixed.  I can’t disagree, but it is a thorny issue!

BTW, for those interested, you can get a little python script I wrote to analyse header stacking from my dev space: http://dev.gentoo.org/~blueness/misc/header-stack.py

[9] In this way Lilblue is similar to Gentoo on FreeBSD.  Rather than using uClibc’s iconv which has issues, Lilblue pulls in dev-libs/libiconv. The additional LDFLAGS are added on a per package basis using /etc/portage/package.env.

[10] https://bugzilla.gnome.org/show_bug.cgi?id=691168

[11] https://bugs.gentoo.org/show_bug.cgi?id=500382

[12] https://bugs.gentoo.org/show_bug.cgi?id=500382

[13] http://git.overlays.gentoo.org/gitweb/?p=proj/releng.git;a=tree;f=tools-uclibc/desktop

3 thoughts on “Lilblue Linux: release 20140218”

  1. Are you *sure* uClibc is faster? “optimised for embedded systems” does not mean “faster on all systems”. In fact being smaller means that it does not have, eg, sse optimised string routines, so it will be very significantly slower than glibc.

    Also has it perhaps occurred to you that some of these gnuism-related bugs might result in security vulnerabilities? So by using uClibc you have rather shot yourself in the head.
    It also seems a little odd that you consider not using secure_getenv to be something that increases security. The clue is in the function name.

  2. I did some benchmarks about a year ago against glibc, uClibc and musl. At that time, I used libc-bench which I added to the tree and convinced myself that uClibc was in general faster, but I do not recall details now. I’ll ressurrect those tests and post back here. I would also be interested in seeing any benchmarking code you have since I like identifying issues like this and improving the uClibc codebase. I am interested in implementing faster functions, but I’m more interested in improving linking. In this respect, musl wins hands down.

    I am aware that secure_getenv() tries to guard against untrusted environment variables on executables with SETUID/SETGID (man 3 getenv). To my knowledge, there are no such instances in Lilblue because I would have seen the compile time error. I also just checked using `readelf -sW $(find / -mount -type f \( -perm /4000 -a -user root \) -o -type f \( -perm /2000 -a -group root \) ) | grep getenv`. Anyhow, I removed getenv() completely from the eudev codebase since it had only a minor function for logging, so this is a mute point there. I don’t know what packages currently use getenv() instead of secure_getenv() and are setuid/setgid to root.

    In general, my feeling is that, if there is an important GNU-ism, then get it into POSIX to force detailed specs for how a function should work while opening up possibilities for different (and possibly better) implementations underneath.

Leave a Reply to James Cancel reply

Your email address will not be published.