Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20200625204456.GA6874@openwall.com>
Date: Thu, 25 Jun 2020 22:44:56 +0200
From: Solar Designer <solar@...nwall.com>
To: announce@...ts.openwall.com, lkrg-users@...ts.openwall.com
Subject: LKRG 0.8

Hi,

After almost a year since the previous release, Linux Kernel Runtime
Guard (LKRG) version 0.8 is finally available:

https://www.openwall.com/lkrg/

A lot has changed since LKRG 0.7 - in fact, so much that we're not
trying to document all of the changes this time (although they can be
seen from the git commits), but rather focus on high-level aspects.

The following major changes have been made between LKRG 0.7 and 0.8:

*) Add support for kernels 5.3+ (JUMP_LABEL batch mode), 5.5+ and 5.6+ (other
   changes in JUMP_LABEL), 5.7+ (non-exported kallsyms_lookup_name symbol)
*) Add support for kernels built with aggressive GCC optimizations, where LKRG
   will now hook the GCC-mangled function names (.isra and .constprop)
*) Add support for kernels lacking functions that LKRG would have hooked but
   can also reasonably work without, which LKRG will now merely warn about
*) Add support for kernels built without CONFIG_USB and/or CONFIG_STACKTRACE,
   and for kernels built with CONFIG_UNWINDER_ORC
*) Add explicit checking for certain required CONFIG_* options to produce
   user-friendly error messages instead of confusing build failures
*) Add support for ACPI S3 (suspend to RAM) and S4 (suspend to disk)
*) Add support for DKMS to Makefile
*) Add experimental support for 32-bit ARM, tested on Raspberry Pi 3 Model B
*) Add experimental support for Raspberry Pi 4, tested on board revision c03112
   (we had already included general support for AArch64 (ARM64) in LKRG 0.7)
*) Add more hooks, most notably on capable() for more likely timely detection
   of exploits that mess with capabilities rather than credentials
*) New logic for detection of namespace escapes (e.g., from Docker containers)
*) Add x86-64 SMAP bit validation and enforcement (similar to that for SMEP)
*) Maintain LKRG runtime configuration in a memory page usually kept read-only
*) Ensure kernel addresses and LKRG's own sensitive information is only logged
   at log_level 4 or higher (non-default)
*) Improve scalability of process tracking database: instead of one RB tree
   guarded by one spinlock, use a 512-entry hash table of RB trees guarded by
   their corresponding 512 read-write locks
*) Introduce a mode (enabled by default) where process credentials integrity
   validation is only frequently performed for the current task (that's about
   to make use of the credentials) and (optionally yet also enabled by default)
   for tasks that are waking up, but infrequently for other tasks (sleeping or
   running without invoking kernel APIs that LKRG knows could use credentials)
*) Redesign LKRG's presentation of its feature set to the user (sysadmin), no
   longer presenting it as having separate Code Integrity and Exploit Detection
   components, but instead LKRG as a whole working to detect various integrity
   violations (not only of code, and possibly caused by exploits) and attacks
*) Introduce many separate knobs (each available as a sysctl and a module
   parameter) for fine-grained tuning of LKRG's detection of violations and
   attacks (validation), as well as its response to those (enforcement)
*) Introduce LKRG validation and enforcement profiles, which are pre-defined
   sets of recommended values of the fine-grained tuning knobs
*) Change the defaults to improve the balance between timely detection and
   effective response vs. performance impact and risk of false positives
*) Rework the optional systemd unit file so that LKRG is loaded at an earlier
   stage of system bootup, but can be disabled via the kernel command-line
*) Rework the documentation reflecting the above changes, replacing INSTALL by
   a much more extensive README, adding CONCEPTS, and replacing the contents of
   PERFORMANCE with up-to-date Phoronix Test Suite benchmarks

Almost all of LKRG files have changed:

$ diff -urN lkrg-0.7 lkrg-0.8 | diffstat | tail -1
 157 files changed, 8120 insertions(+), 5559 deletions(-)
$ find lkrg-0.8 -type f | wc -l
163

Like before, this release is mostly due to work by Adam 'pi3' Zabrocki.
We also had direct contributions by Mariusz Zaborski.  I proposed many
of the changes above (sometimes with specific detail and code snippets)
and reworked the documentation.  I don't enjoy being just the manager
and the documentation guy for LKRG, but I think I, well, manage.  This
release was also influenced by many on the lkrg-users mailing list.

In related news, Patrick Schleizer packaged LKRG with DKMS for Debian
(and compatibles), originally for its use in Whonix:

https://www.whonix.org/wiki/Linux_Kernel_Runtime_Guard_LKRG

Because of the (unplanned) delay between LKRG 0.7 and 0.8, Patrick used
git snapshots of LKRG for this packaging, and Adam started signing git
commits on Patrick's request.

The packaging above brought LKRG to the attention of Michael Larabel of
Phoronix, who ran benchmarks of LKRG as packaged for Whonix as of
February 25, 2020 and published an article on the results:

https://www.phoronix.com/scan.php?page=article&item=linux-lkrg-performance&num=1

As LKRG developers, we found most of the results reasonable, but were
surprised by some.  Anyhow, the overall performance impact of LKRG as
seen from the geometric mean of all test results was around 4.4%.  This
was before the many performance-related improvements now included in
LKRG 0.8.  We contacted Michael, and he kindly instructed us how to
rerun the exact same set of 58 tests.  Our own results, now included in
the PERFORMANCE file, show LKRG 0.8 have an overall performance impact
of around 2.5% for the heavy profile (which is the default) and around
2.0% for the light profile, although the individual test results vary.

We expect Michael will rerun the benchmarks for LKRG 0.8 on his end and
publish a new article soon.

Also of note is Juho Junnila's Master's Thesis "Effectiveness of Linux
Rootkit Detection Tools", which shows LKRG as by far the most effective
kernel rootkit detector of those tested:

https://www.openwall.com/lists/lkrg-users/2020/06/14/5

In particular, when LKRG is loaded before the rootkit, it detected 8 out
of 9 kernel rootkits tested: Diamorphine, Honey Pot Bears,
LilyOfTheValley, Nuk3 Gh0st, Puszek, Reptile, Rootfoo Linux Rootkit,
Sutekh.  There were no false positives.  No other tested rootkit
detector was anywhere close to LKRG's effectiveness at detecting kernel
rootkits, with AIDE, OSSEC, and Rootkit Hunter detecting 2 out of 9
each, and Chkrootkit detecting none.  These other detectors did,
however, detect some userspace rootkits, which LKRG doesn't try to.  The
combination of AIDE and LKRG is shown to be most effective, detecting 14
out of 15 rootkits total (both user and kernel space ones).  None of the
other tools detected the one not-so-rootkit undetected by AIDE and LKRG.

Ilya Matveychikov has collected his LKRG bypass PoCs in a repository:

https://github.com/milabs/lkrg-bypass

Some of these were already mitigated since various versions of LKRG, but
it is helpful to have them all in one place.

Finally, for those who read Polish, there's this recent blog post by
Mikhail Morfikov describing almost LKRG 0.8 (but not quite) and how to
package it for Debian (similar to but different from Whonix's):

https://morfikov.github.io/post/modul-lkrg-linux-kernel-runtime-guard/

As usual, we welcome any feedback on lkrg-users.

Alexander

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.