The following major changes have been made between LKRG 0.9.8 and 0.9.9:

 *) Support Linux 6.11+ and stable 6.10.10+
 *) Support new longterm kernels 5.10.220+
 *) Support new CentOS Stream 9 kernel 5.14.0-470.el9 and beyond (to RHEL 9.5)
 *) Support CONFIG_JUMP_LABEL batch mode also on ARM64
 *) Re-support build without CONFIG_TRACEPOINTS (was broken in 0.9.8)
 *) pCFI: Upgrade "Frame pointer is not on the stack" to ALERT with enforcement
 *) Simplify seccomp validation (should help portability to more kernel builds)


The following major changes have been made between LKRG 0.9.7 and 0.9.8:

 *) Add optional remote kernel message logging, including the sending component
    in LKRG itself and the receiving/logging counterpart in a userspace daemon,
    as well as additional utilities to generate a public/secret keypair and to
    process the logs, and documentation in LOGGING
 *) Add support for RHEL 8.8+
 *) RPM spec file improvements to make it work or properly fail in a wider set
    of circumstances, and to use the "weak-modules" script if available so that
    on RHEL and its rebuilds the same LKRG package build works across different
    kABI-compatible kernel revisions/builds
 *) More complete documentation of the build requirements


The following major changes have been made between LKRG 0.9.6 and 0.9.7:

 *) Support new mainline kernels 6.4 to 6.5.x, and hopefully beyond
 *) Support new RHEL 9.1 and 9.2 kernels, and hopefully beyond
 *) Add RPM spec file for Red Hat'ish distros (usable via "rpmbuild -tb" on our
    release tarball)
 *) Add Arch Linux's /usr/bin/modprobe path to usermodehelper allow list
 *) Bootup script changes
 *) Continuous Integration updates


The following major changes have been made between LKRG 0.9.5 and 0.9.6:

 *) Support new mainline kernels 6.1-rc*, 6.1, and hopefully beyond
 *) Support kernels 5.19 and beyond on AArch64
 *) Support new RHEL 8.6 update and RHEL 8.7 kernels
 *) Support new CentOS Stream 9 aka upcoming RHEL 9.2 kernels
 *) Add a couple of distros' default pathnames to usermodehelper allow list
 *) Validate tasks' real UIDs/GIDs even when effective ones pass validation
    (previously, this check was normally bypassed as an optimization)
 *) Add synchronization logic around sysctl updates and other module (un)loads
    (previously, some concurrent events of this sort could lead to a crash on
    attempting to write to our read-only page)
 *) Test whether kretprobes work correctly at LKRG loading time and re-test
    periodically (previously, LKRG would only detect disabling of kretprobes
    after it's loaded, and only indirectly - through kernel code hash changes)
 *) Set kretprobes' maxactive based on actual number of possible logical CPUs
    (previously, we used a hard-coded value, which would more likely result in
    missed hook function invocations on systems with more CPUs)
 *) Continuous Integration updates, including testing on AArch64


The following major changes have been made between LKRG 0.9.4 and 0.9.5:

 *) Support new longterm kernels 5.10.133+
 *) Rework the logic supporting OverlayFS (notably used by Docker) to support
    a wider variety of kernel versions and builds


The following major changes have been made between LKRG 0.9.3 and 0.9.4:

 *) Support new longterm kernels 5.15.40+
 *) Support the OpenRC init system
 *) Make log messages more consistent and suitable for both automated analysis
    and human consumption, as well as easier to maintain
 *) Introduce LKRG's own message severities and categories, which are separate
    from (but mapped onto) the kernel's and are included in messages themselves
 *) Many minor bug fixes, issue workarounds, and significant code cleanups
 *) Rename the module from p_lkrg to lkrg
 *) Add instructions on installing using DKMS
 *) Continuous Integration updates


The following major changes have been made between LKRG 0.9.2 and 0.9.3:

 *) Support new mainline kernels 5.17.x, 5.18-rc*, and hopefully beyond
 *) Support loading into Xen PV guest kernels even on older CPUs without UMIP
 *) Fix build on latest CentOS Stream 8 and upcoming RHEL 8.6+
 *) Fix build on CentOS Stream 9
 *) Fix build on openSUSE Leap
 *) Continuous Integration and debugging build updates and improvements


The following major changes have been made between LKRG 0.9.1 and 0.9.2:

 *) Support new stable and mainline kernels 5.14 to at least 5.16-rc*
 *) Support new longterm kernels 5.4.118+, 4.19.191+, 4.14.233+
 *) Support various CONFIG_SECCOMP configurations
 *) Fix a false positive possible because of race on SECCOMP_FILTER_FLAG_TSYNC
    where LKRG started to validate other threads' seccomp state too early
 *) Fix support of CONFIG_HAVE_STATIC_CALL on Linux 5.10+ to avoid a race with
    unloading of other modules
 *) Support the "nolkrg" kernel parameter in LKRG itself (not only in systemd)
 *) Log the blocked module name when lkrg.block_modules=1
 *) Install/expect the sysctl settings in /etc/sysctl.d/01-lkrg.conf
 *) Add dkms.conf
 *) Continuous Integration and debugging build updates and improvements


The following major changes have been made between LKRG 0.9.0 and 0.9.1:

 *) Support CONFIG_HAVE_STATIC_CALL on Linux 5.10+
 *) Fix SELinux integrity violation false positive bug (introduced into LKRG in
    March 2021 and manifesting itself on Linux 4.17+ when SELinux is already in
    enforcing mode when LKRG is loaded)
 *) Improve systemd service and its installation, add /etc/sysctl.d/lkrg.conf
 *) Add the debian/ directory in order to support the Debian build system based
    on pbuilder/dpkg-buildpackage


The following major changes have been made between LKRG 0.8.1 and 0.9.0:

 *) Support new mainline kernel versions 5.8 to 5.12 (inclusive) and new stable
    kernels 5.4.87+ (which include some back-ports from 5.8+)
 *) Support new RHEL kernels up to RHEL 8.4's (inclusive)
 *) Support building LKRG in the kernel tree (not only as a standalone module),
    as a module or linking into the kernel image (see scripts/copy-builtin.sh)
 *) Support CONFIG_FUNCTION_TRACER with or without CONFIG_DYNAMIC_FTRACE
 *) Support various CONFIG_OPTPROBES configurations
 *) Support loading overlayfs[2] after LKRG (e.g., by Docker; previously, the
    overlayfs[2] module had to be loaded before LKRG for Docker to work)
 *) "Support" CONFIG_GCC_PLUGIN_RANDSTRUCT (don't monitor SELinux if enabled)
 *) Explicitly do not support RT kernels
 *) Fix support for 32-bit x86 (was unintentionally broken in LKRG for ages,
    but could mostly work on many pre-5.7 kernel and LKRG builds by "luck")
 *) Fix detection of process user/group ID corruption to cover any unexpected
    changes (previously, only numerically lower new IDs, as exploits normally
    use, would be detected - a limitation left over from early LKRG testing)
 *) Fix logging of WP/SMEP/SMAP violations on systems with SMAP in the "log and
    accept" mode (previously, one such violation could mute logging of others)
 *) Add detection of ADDR_LIMIT corruption attacks
 *) Remove validation of waking-up tasks (drop pint_validate=2)
 *) Replace execve(2) hooks (instead hook security_bprm_committing_creds and
    security_bprm_committed_creds, which shortens the race window for exploits)
 *) Replace ptrace(2) hooks (instead hook security_ptrace_access)
 *) Simplify UMH blocking and make it compatible with CPA-protected pages
 *) Simplify and speed up do_exit hook (no need to validate a dying process)
 *) Many other changes under the hood to make LKRG easier to maintain and debug
 *) Integrate LKRG with out-of-tree (a tool to assist kernel module testing)
 *) Integrate LKRG with mkosi (systemd's tool for generating a test boot image)
 *) Continuous Integration setup: boot tests on GitHub Actions using mkosi
    (with Ubuntu's release kernels and their daily builds of mainline kernels)


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

*) Drop init_module() and delete_module() syscall hooks, which were no longer
   justified now that we hook capable() yet contained a nasty bug (first
   reported by Jason A. Donenfeld) allowing a user to trigger an Oops (read via
   a near-NULL pointer) on 64-bit Linux 4.17+
*) Update CONCEPTS to note the risk of running with untested kernel versions
*) Update PERFORMANCE to refer to Phoronix article and raw results on 0.8


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


The following changes have been made between LKRG 0.6 and 0.7:

*) Refactor LKRG code to support multiple CPU architectures
*) Add experimental support for ARM64
*) Add experimental support for grsecurity kernels (with some limitations)
*) Add support for kernels 5.1 and 5.2 (and hopefully beyond)
*) Add support for kernels without enabled CONFIG_DYNAMIC_DEBUG
*) Add support for kernels without enabled CONFIG_ACPI
*) Add support for kernels without enabled CONFIG_STACKTRACE
*) Add support for kernels with enabled CONFIG_STATIC_USERMODEHELPER
*) [CI] Fix race condition with *_JUMP_LABEL engine resulting in potential
   deadlock when LKRG is initialized in parallel with other heavy kernel module
   (un)loading events
*) [CI] Re-enable self-hashing
*) [ED] Change the logic how LKRG tracks a newly created task in the system
*) [ED] Rewrite internal logic how LKRG synchronizes with the task's resources
*) [ED] Filter our kernel threads and system-init process when validation is
   performed bypassing threads iteration
*) [ED] Disable IRQ in most cases when LKRG's PIDs database lock is taken.
   Otherwise, we could have potential race and deadlock with kprobe engine
   itself, and SoftIRQs could deadlock with LKRG's pCFI.
*) [ED] Fix potential FP during LKRG unloading procedure and add memory barrier
*) [ED] Fix logic for *init_module/delete_module for kernels with
   CONFIG_ARCH_HAS_SYSCALL_WRAPPER
*) [ED] Fix FP (race condition) in pCFI in glitching scenario during process
   update, and add memory barrier
*) [ED] Fix potential glitch in pCFI
*) [ED] Add support for OverlayFS (which is commonly used by Docker)
*) [ED] Whitelist Ubuntu Apport (thanks to Pawel Krawczyk)
*) [ED] Enforce stack pointer validation on lookup_fast function
*) [ED] Add SMEP/WP bit verification (and re-enforcement) in more places
*) [ED] Refactor some of the logic to be compatible with x86 lacking SMEP
*) [ED] Add new sysctl lkrg.smep_panic (only on x86, enabled by default)
*) [ED] Add new sysctl lkrg.umh_lock (disabled by default)
*) Update INSTALL to document the new sysctl's and the previously undocumented
   lkrg.hide sysctl
*) Minor change of initialization logic
*) Add potential debug compilation option to Makefile
*) Mute the most noisy STRONG_DEBUG output by default
*) Don't export global CFLAGS since it might be incompatible when LKRG is part
   of a bigger project's build
*) Restore terminal colors when systemd service installation fails


The following changes have been made between LKRG 0.5 and 0.6:

*) [CI] Protect SMEP bit in CR4 and WP bit in CR0 on x86 architecture
*) [CI] Reimplement *_JUMP_LABEL support: simpler and needs a lot less memory
*) [CI] Propagate errors when kzalloc() fails
*) [ED] Introduce pCFI mitigation (poor man's Control Flow Integrity) against
   unintended invocation of a few kernel functions especially useful in
   exploits
*) [ED] Lock down the usermodehelper interface with a whitelist of programs
*) [ED] Fix false positive on seccomp(SECCOMP_SET_MODE_FILTER,
   SECCOMP_FILTER_FLAG_TSYNC, ...) failing, where we must revert all threads'
   settings but did not (we do now)
*) [ED] Freeze all user mode processes during Exploit Detection initialization
   to avoid false positives
*) [ED] Minor change in how SIGKILL is delivered to the corrupted task
*) Fix build error on Linux 4.17+ without CONFIG_ARCH_HAS_SYSCALL_WRAPPER
*) Add LKRG early boot systemd unit file.  (Similar optional functionality for
   other init systems may be added later.  Contributions are welcome.)
*) Add install/uninstall make targets, which deploy/remove the systemd service


The following changes have been made between LKRG 0.4 and 0.5:

*) [CI] Add *_JUMP_LABEL support for kernel modules (a major change)
*) [CI] Add support for "cold" function versions generated by new GCC -
   necessary to correctly handle *_JUMP_LABEL
*) [CI] Change output message format when *_JUMP_LABEL was detected for kernel
   module's .text section
*) [CI] Add new sysctl interface - optional panic() on CI verification failure
*) [ED] Hook generic_permission() instead of may_open()
*) [ED] Hook and correctly handle override_creds() / revert_creds()
*) Add Mikhail Klementev's patches for Makefile, .gitignore and missing include


The following changes have been made between LKRG 0.3 and 0.4:

*) [ED] Fix a potential kretprobe glitch that could happen in a very rare
   corner case on heavily loaded SMP machines (resulting in a false positive)
*) [ED] Change some of the printed messages for log_level=4
*) [ED] Add support for 4.17+ kernels. This is a pretty big change addressing:
      a) New logic of how syscall stubs are created; CONFIG_X32_X86 and
         CONFIG_COMPAT now have separate stubs
      b) SELinux variables are now accumulated in one structure


The following changes have been made between LKRG 0.2 and 0.3:

*) [ED] Fix false positive caused via potential race condition when child
   process might be faster than mother returning from the fork()
*) [ED] Change the logic and loglevel for message printed when racy situation
   at fork() appears
*) [CI] Change assigned probabilities when integrity routine will be fired


The following changes have been made between LKRG 0.1 and 0.2:

*) Add support for being loaded at early boot stage (e.g. from initramfs)
*) [CI] Add a new sysctl to control whether LKRG performs code integrity checks
   on random events (or only at regular intervals)
*) Reduce performance impact, e.g. in our specific test case:
   -> Average cost of running a fully enabled LKRG => 2.5%
   -> Average cost of running LKRG without the code integrity checks on
      random events (disabled with the new sysctl) => 0.7%
*) [CI] Fix a potential deadlock bug caused by get_online_cpus() function,
   which might sleep if CONFIG_PREEMPT_VOLUNTARY=y
*) [CI] Fix dynamic NOPs injected by *_JUMP_LABEL for MWESTMERE
*) [CI] Remove false positives caused by *_JUMP_LABEL in corner case scenarios
*) [ED] Remove false positives when kernel executes usermode helper binaries


The following changes have been made between LKRG 0.0 and 0.1:

*) Support RHEL 7.4 kernels
*) Make new compiler happy (gcc 7.3+)
*) Improve Makefile
*) Improve Exploit Detection performance and hardened 'off' flag
*) Add support for kernel 4.15
*) Use GPLv2 LICENSE
*) Add INSTALL, CHANGELOG and PATREONS file
*) Move SELinux integrity check to the workqueue
*) Fix how *_JUMP_LABEL is handled when 0xCC byte is injected


Legend:
[CI] - Code Integrity
[ED] - Exploit Detection
