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:

VirtualBox - Restore snapshot after kernel panic testingLinux 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. The 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.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.