For general information on LKRG, please visit its main wiki page.
The examples below were written/recorded in March 2017 through April 2018. We released LKRG 0.0 in January 2018. The examples are still mostly valid until LKRG 0.7 released in July 2019. We've since reworked the sysctl's for LKRG 0.8+ released in June 2020, and some LKRG messages are now different.
After successfull compilation of the project, “output” directory is created with the following files:
This is the core of the project. Module itself accepts one parameter which determines the default logging level. By default, it is “active” level (levels will be described in details in the next section). Each level of logging is represented by numbers. By providing numbers between 0-4 or 0-6 (if compiled with debugging option) LKRG will immediately use this level even during installation in the kernel memory. It is a very useful option for debugging purpose when LKRG encounters a problem during installation in the system:
Installation of LKRG is exactly the same as loading normal kernel module. As soon as system is installed it starts the work. If default logging level is used, LKRG produces one short sentence saying that system is clean unless corruptions are detected. Otherwise LKRG informs where corruption happened, e.g.:
If system is started with more detailed log level, more information will be visible, e.g.:
(this is not the latest version of the project so might not have acquired all information)
If debugging compilation is available, it may produce enormous amount of information regarding the running system (including every function name where LKRG is entering and leaving, etc.). Sometimes even default “active” log level might be too noisy (every time when LKRG checks the system, one-line status information will be produced in case the system is clean). That’s why “none” log level option was introduced. System at that log level is quiet until abnormal situation is detected by LKRG. In that case only alerting logs will be produced.
The project has built in a sysctl interface which enables the interaction between the administrator and LKRG. By default 4 different options are available:
root@pi3-ubuntu:~/p_lkrg-main# sysctl -a|grep lkrg lkrg.block_modules = 0 lkrg.clean_message = 1 lkrg.force_run = 0 lkrg.log_level = 1 lkrg.random_events = 1 lkrg.timestamp = 15
Here is an example of how to use the blocking module functionality:
root@pi3-ubuntu:~/p_lkrg-main# sysctl lkrg.block_modules=1 lkrg.block_modules = 1 root@pi3-ubuntu:~/p_lkrg-main# rmmod btrfs rmmod: ERROR: Module btrfs is not currently loaded root@pi3-ubuntu:~/p_lkrg-main# modprobe btrfs modprobe: ERROR: could not insert 'btrfs': Operation not permitted root@pi3-ubuntu:~/p_lkrg-main# modprobe btrfs modprobe: ERROR: could not insert 'btrfs': Operation not permitted root@pi3-ubuntu:~/p_lkrg-main# modprobe btrfs modprobe: ERROR: could not insert 'btrfs': Operation not permitted root@pi3-ubuntu:~/p_lkrg-main# sysctl lkrg.block_modules=0 lkrg.block_modules = 0 root@pi3-ubuntu:~/p_lkrg-main# modprobe btrfs root@pi3-ubuntu:~/p_lkrg-main# rmmod p_lkrg
It is possible to compile LKRG project with “hiding” feature. In that case LKRG exports an extra option via sysctl interface to hide itself in the system:
Unhiding functionality is a bit of complex operation if module was previously hidden. LKRG module object is synthetically created (which implies some referenced values are incorrect) and it is linked again in proper linked lists. After all, you can safely unload LKRG but you must use ”–force” option. Example:
root@pi3-ubuntu:~/p_lkrg-main# sysctl -a |grep lkrg lkrg.block_modules = 0 lkrg.clean_message = 1 lkrg.force_run = 0 lkrg.hide = 0 lkrg.log_level = 0 lkrg.random_events = 1 lkrg.timestamp = 15 root@pi3-ubuntu:~/p_lkrg-main# lsmod|grep p_ p_lkrg 94208 0 root@pi3-ubuntu:~/p_lkrg-main# sysctl lkrg.hide=1 lkrg.hide = 0 root@pi3-ubuntu:~/p_lkrg-main# lsmod|grep p_ root@pi3-ubuntu:~/p_lkrg-main# sysctl lkrg.hide=0 lkrg.hide = 1 root@pi3-ubuntu:~/p_lkrg-main# lsmod|grep p_ p_lkrg 94208 -2 root@pi3-ubuntu:~/p_lkrg-main# rmmod --force p_lkrg root@pi3-ubuntu:~/p_lkrg-main#
Linux boots UP kernel as long as the system has only 1 (V)CPU with 1 core. However, if hot-plugging (V)CPU is supported, OS during run-time might decide to boot SMP kernel without restarting the entire OS when a new (V)CPU or core appears. This is very critical situation from the LKRG point of view – mainly because hashes from the most sections will change. Some of the functionalities are different for UP and for SMP. LKGP takes this into account and correctly rebuilds internal database as soon as this situation happens. It can be seen as follows:
Let’s add 1 more VCPU:
New CPU was correctly added but it is still in offline state:
We must change cpu1 status to online to make it work and initialize. If we do it, we can see following:
As soon as 2nd CPU became online, kernel switched to SMP code, and boot itself on SMP configuration via “smpboot” process. This operation also forced some modules to be reloaded and since LKRG was configured with enabled “blocking modules” feature, it blocked these operations. Additionally, LKRG added new CPU’s critical metadata to the database for individual protection. It will send now IPI to each CPU individually, forcing them to run checking routine. If we enable debugging option (doesn’t need to be strong debug), we can see in logs it is really happening (LKRG logs):
LKRG also correctly handles hot-unplugging CPUs or making them offline:
LKRG logs:
Again, if we enable the debug logs we can see offline CPU is present but not active and metadata only from 1 CPU is protected (but offline CPU’s state is still protected):