|
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.