What are kernel modules ?
Linux kernel modules (LKMs) are loadable pieces of code think of them as plugins that can be added or removed from the Linux kernel on demand, without requiring a reboot. This allows updates to drivers without restarting the system, making the Linux kernel more lightweight and quicker to boot. Itβs also more memory-efficient, as only the loaded modules consume memory, unlike when all drivers are compiled directly into the kernel.
Kernel modules are typically stored in /lib/modules/ and have a .ko (kernel object) file extension. However, a module doesnβt need to reside in this directory to be loaded.
Types of Modules:
- Security: AppArmor (to restrict application access to system resources.)
 - Device Drivers: NVIDIA GPU drivers.
 - Filesystems: 
ntfs.koΒ for NTFS support. - Networking: VPN modules likeΒ 
tun.ko. 
Interacting with kernel modules
Finding existing modules
ls -l /lib/modules/$(uname -r)/*Viewing Loaded modules
lsmod | less
Inspecting module details
modinfo bluetooth
Writing your own kernel module
Although Linux kernel modules are written in C, they differ from user-space programs because the Linux kernel does not use the standard C library (glibc). Functions like printf are unavailable in kernel space, as glibc is designed for user-space applications and is not accessible from within the kernel.
However, the naming conventions in the kernel are often similar. For example, printf in user space has a kernel equivalent called printk.
Hereβs a example of a linux kernel module that prints our given text in dmesg :
#include <linux/module.h>
#include <linux/kernel.h>
static int __init mymodule_init(void) {
    printk(KERN_INFO "Hack the planet!\n");
    return 0;
}
static void __exit mymodule_exit(void) {
    printk(KERN_INFO "Your module is unloaded (:\n");
}
module_init(mymodule_init);
module_exit(mymodule_exit);Easiest way to compile this into a kernel module is to make a Makefile:
obj-m += custommodule.o
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) cleanWe can now compile our code using make in the directory our code file resides in.
Loading & Unloading modules
To load and unload kernel modules we can use utilities such as :
insmodrmmodmodprobe
The key difference between insmod/rmmod and modprobe is that modprobe can handle module dependencies, whereas insmod and rmmod cannot. Dependency handling means that the kernel automatically loads any additional modules required for a given module to function properlyβsuch as hardware drivers or other kernel components.
When you use insmod to load a module, it does not automatically load its dependencies. If a required module is missing, insmod will fail and return an error. In contrast, modprobe will detect and load all necessary dependencies before loading the target module, ensuring proper functionality.
Loading
insmod custommodule.koOutput in dmesg : 
Visual representation of a Module getting loaded

Unloading
rmmod custommoduleOutput in dmesg : 
Visual representation of a Module getting unloaded

Debugging issues
Here we are common issues that we can face when dealing with linux kernel modules .
Unknown symbol in module
This error accurs when a function or a variable is exported by another module and that module isnβt loaded (dependency issue) . This can be resolved by simply using modinfo to check the dependency modules and loading them using either modprobe or insmod
modprobe --show-depends bluetoothOutput: 
Module wonβt unload
Error such as Error : Module is in use This can be due to modules resources are still open (e.g /proc entries)
Invalid module format
This happens due to kernel version mismatch or kernel abi mismatch . We can simply recompile against the current kernel header by using make with our code again
Security tools in the linux kernel
SelinuxApparmorEBPF
In order to understand these systems we have to understand different security levels we have when it comes to a systems security . We have levels
DAC: User controlled permissions such aschmodMAC: System wide policies inforced by the kernel e.g :selinux,apparmorRbac: role based permissions e.g :kubernetes
Selinux
This is a (mac) system intergrated into the linux kernel and was developed by NSA , It enforces strict policies that define how processes and users interact with files , directories and network ports
Modes
Enforcing: Blocks unauthorized actionsPermissive: Logs but allows actionsDisabled:. Turns off
Key-Features :
- Labels (contexts) : Every file , process and port has a security label (e.g: 
http_port_t) - Policies : Rules define allowed interactions (e.g : can 
httpd_tread files labeldhttpd_content_t?)>) 
Usage To check the current status of selinux we use sestatus
sestatusTo change the rules we use setenforce
setenforce 0 # permissive
setenforce 1 # EnforcingSetting up rules with selinux can be done using semanage
semanage port -a -t http_port_t -p tcp 8080Above we allow apache to access a non-standard port 8080
Checking currently allowed ports
sudo semanage port -lApparmor
This is a Linux security module (LSM) that provides Application-level mac via profiles and its a kernel module. Unlikeselinux` , it uses path-based restrictions rather than labels .
Key Features :
- Define what files,capabilities and network access an application has
 
Modes :
Enforce: Blocks unauthorized actionscomplain: logs but allows violations
Usage
Check Status :
aa-statusPutting a program in complain mode :
aa-complain /usr/sbin/apache2Generate a profile :
aa-genprof /usr/bin/chromiumEBPF
EBPF stands for Exnteded berkeley packet filter and is a kernel-level virtual machine allowing sandboxed programs to run without modifying the linux kernel . It also includes Dynamic tracing (Monitor network traffic , function calls , syscalls)
For usage refer to : https://ebpf.io/what-is-ebpf/


