1. Overview
A Linux kernel panic is an unexpected, unrecoverable error that causes the kernel to stop working. As a result, the system halts all operations.
It’s usually caused by software bugs or hardware malfunctions, such as a corrupt file system, defective RAM, or overheating. Because the system becomes unresponsive, a manual reboot is the only way to attempt recovery.
In this tutorial, we’ll look at some methods of intentionally causing a kernel panic from the terminal. This information is intended for testing in a safe and isolated environment. We strongly advise against testing kernel panics on production systems or systems with valuable data.
2. Precautions and Test Environment
Let’s remember that a kernel panic is a serious error that can result in data loss, corruption, or hardware damage.
We’ll test all kernel panic examples using a Virtualbox virtual machine. This is a good choice for any potentially destructive testing because we can avoid damaging our real system. In addition, we can easily roll back any changes, errors, or data loss using snapshots, as shown in the following image:
Linux Mint 21.1 will be our testing environment. However, the following commands will work on any Linux distribution, as they are based on standard Linux kernel functionality. Yet, there may be some differences in how certain commands or tools are installed or configured on different distributions, so we may need to modify the commands slightly.
3. Sending a SysRq (System Request) Command
SysRq (System Request) is a way to ask the kernel to execute a command by pressing a key combination or using the terminal. Since we’re using a virtual machine for testing, it’s better not to use dangerous keyboard shortcuts, as they might work in the host instead of the guest.
In the terminal, SysRq invocation via /proc/sysrq-trigger is always allowed in all Linux distributions. T***he list of all available operations is in the command keys table, where “c*” stands for “system crash”. So let’s run as root the following command, which sends “c” to /proc/sysrq-trigger to completely freeze the system:
# echo c > /proc/sysrq-trigger
The SysRq interface is always available, even when the system is unresponsive. Thus, using it to cause a crash may be useful in certain hanging circumstances to analyze a crashdump containing the state of the system.
4. Kernel’s panic() Function
In Linux kernel development, panic() is a function we can call to cause a kernel panic. It’s defined in include/linux/kernel.h and implemented in kernel/panic.c. It takes a single argument, which is a format string, and optional arguments as parameters, similar to printf().
Let’s make sure we have the necessary packages to build kernel modules in order to do a test:
# apt install build-essential make gcc
Then, in our home, let’s create a folder called kernelpanic, and in it, the files kernelpanic.c and Makefile.
Let’s see the contents of kernelpanic.c:
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL"); // required by the compiler
int init_module(void){
panic("Kernel Panic test");
return 0;
}
Makefile contains the following commands. Let’s note that the third line starts with a tab (/t), not a series of spaces:
obj-m += kernelpanic.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Now we’re ready to compile the module with make:
$ cd kernelpanic/
~/kernelpanic$ make
make -C /lib/modules/5.15.0-69-generic/build M=/home/francesco/kernelpanic modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-69-generic'
[...]
LD [M] /home/francesco/kernelpanic/kernelpanic.ko
[...]
Finally, to cause a kernel panic, let’s insert kernelpanic.ko into the kernel:
# insmod kernelpanic.ko
In general, we should use panic() only when we believe that it’s impossible or undesirable to continue executing the code.
5. NULL Pointer Dereference
In C, a pointer is a variable that stores the address of another variable. Dereferencing a pointer means accessing the value to which the pointer points. A pointer with a NULL (zero) value doesn’t point to a valid memory location, so dereferencing it results in an invalid memory access. In kernel modules, it’s a common programming error and will cause a kernel panic if the value of /proc/sys/kernel/panic_on_oops is 1.
Let’s inspect kernel.panic_on_oops:
$ sysctl kernel.panic_on_oops
kernel.panic_on_oops = 0
In this case, 0 means that the kernel will attempt to continue operation when it encounters an oops, which is a serious but not fatal error. In this scenario, system reliability is compromised. To tell the kernel to panic immediately, let’s set kernel.panic_on_oops to 1:
# echo "1" > /proc/sys/kernel/panic_on_oops
# sysctl kernel.panic_on_oops
kernel.panic_on_oops = 1
Let’s create a kernelnpd folder in our home and put the following null-pointer-dereference.c and Makefile files in it.
The null-pointer-dereference.c module will generate the NULL pointer dereference error:
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL"); // required by the compiler
int init_module(void)
{
char *killer = NULL; // this is the pointer with NULL value
*killer = 1; // it puts the value 1 in the memory area pointed to, which is NULL, i.e., nonexistent
return 0;
}
The following is the Makefile. As in the previous example, let’s ensure that the third line starts with a tab (/t), not a series of spaces:
obj-m += null-pointer-dereference.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Again, let’s compile with make:
$ make
[...]
LD [M] /home/francesco/kernelnpd/null-pointer-dereference.ko
[...]
Finally, let’s insert the module to cause an immediate kernel panic:
# insmod null-pointer-dereference.ko
As a general rule, we should always check if a pointer is NULL before dereferencing it or use programming techniques to do the check automatically.
6. Conclusion
In this article, we’ve looked at some methods of intentionally causing a kernel panic for testing in a controlled environment. However, they can be risky, forcing us to reboot, and can result in data loss or system instability. Typically, these tests are meaningful only to developers.
In general, we should prevent kernel panics by keeping our systems up-to-date with the latest security patches, regularly checking hardware components for signs of wear or damage, and avoiding risky software installations or system changes.