As we continue to evolve and improve the Oracle Linux user experience, one of our recent focuses was on enhancing the packaging model for Unbreakable Enterprise Kernel (UEK) 8. In this blog post, we delve into the details of the new packaging changes in UEK 8.
Introduction to UEK 8 packaging
In UEK 8 we’ve partitioned the kernel modules into several subpackages, thereby providing system administrators, or users, with greater control over the installation and management of kernel modules. This also provides a mechanism to reduce the potential attack surface.
New Subpackages in UEK 8
With the UEK 7 release, we have these packages:
kernel-uek
kernel-uek-*
RPMs, defining a set equal to the same in earlier UEK releases
kernel-uek-core
vmlinux
, config files, System.map
files, initramfs
and so on. These files reside in the /boot
directory on installing the RPM
kernel-uek-modules-core
kernel-uek-modules
kernel-uek-modules-extra
These packages offer limited control over the specific modules to be installed, which can make it challenging to minimize the attack surface or disk usage by selectively installing only the necessary modules.
With UEK8, the above packages continue to exist, while these new ones are introduced:
kernel-uek-modules-desktop
kernel-uek-modules-usb
kernel-uek-modules-wireless
kernel-uek-modules-extra-netfilter
netfilter
modules
kernel-uek-modules-deprecated
This figure provides an overview of the structure of these packages:
The need for new subpackages
The new set of subpackages provide a way for the user to retain only those kernel-uek-modules*
packages that they require and to remove any kernel-uek-modules*
packages that they don’t need.
Modules classified as desktop
use – such as laptop drivers, webcam drivers, video drivers, and sound drivers – which aren’t commonly used on servers, are now moved to the kernel-uek-modules-desktop
subpackage.
Similarly, USB drivers are moved to the kernel-uek-modules-usb
subpackage, and wireless drivers are moved to the kernel-uek-modules-wireless
subpackage.
Many netfilter
modules now have modern alternatives that are more actively maintained. Rather than removing these modules altogether, we’ve moved the less-commonly used into the kernel-uek-modules-extra-netfilter
subpackage.
As we continually enable new features and integrate new drivers from the upstream Linux kernel, we also identify instances where certain drivers have been retired, or removed entirely, in newer Linux releases. To address this, we proactively monitor these changes and move such drivers to the kernel-uek-modules-deprecated
subpackage to provide users with some advance notice of modules that will be retired in a future UEK release.
As mentioned before, it’s possible to reduce the number of modules installed on a system running UEK 8. For example, on a server system, it’s likely that certain classes of drivers, such as those for webcams, touchscreens, or other desktop-specific hardware, are unnecessary. In such cases, users can remove the kernel-uek-modules-desktop
subpackage, which can help minimize the attack surface by eliminating potential exposure through unused drivers.
As we’ve discussed, the introduction of these subpackages offers users greater flexibility and control over their system configuration. By providing a modular approach, users can optimize their systems for specific use cases, making it easier to manage their environment.
Module mapping and a modprobe
enhancement
Module mapping
To make it easier for users to navigate the increased number of packages, a mapping of modules to their corresponding subpackages is provided in a file within the kernel-uek-core
package. This file, named modules.packages
, contains the mapping of module to its subpackage name – each line has the format:
module_name subpackage_rpm_name
The modules.packages
file is in the /lib/modules/$(uname -r)
directory:
$ cat /lib/modules/6.12.0-0.20.20.el9uek.x86_64/modules.packages 8021q kernel-uek-modules-core-6.12.0-0.20.20.el9uek.x86_64 acpi-cpufreq kernel-uek-modules-core-6.12.0-0.20.20.el9uek.x86_64 acpi_extlog kernel-uek-modules-core-6.12.0-0.20.20.el9uek.x86_64 acpi_ipmi kernel-uek-modules-core-6.12.0-0.20.20.el9uek.x86_64 ... tca6416-keypad kernel-uek-modules-desktop-6.12.0-0.20.20.el9uek.x86_64 tda7432 kernel-uek-modules-desktop-6.12.0-0.20.20.el9uek.x86_64 ... wil6210 kernel-uek-modules-wireless-6.12.0-0.20.20.el9uek.x86_64 zd1211rw kernel-uek-modules-wireless-6.12.0-0.20.20.el9uek.x86_64
modprobe
enhancement
We’ve also enhanced modprobe
to be aware of the new packaging structure. So, when a module is installed, modprobe
automatically loads it. If the corresponding package containing the module isn’t installed, modprobe
now displays the name of the subpackage containing the module, providing users with clear guidance on which package to install.
For example, on a system with UEK 8 running, and where the kernel-uek-modules-desktop
subpackage hasn’t been installed, we can try to load a module from that package to see whether this functionality works correctly.
First, check that we’re running UEK 8:
[opc@uek8-vm ~]$ uname -r 6.12.0-0.20.20.el9uek.x86_64
Next let’s load the 8021q
module to check that module loading is working correctly:
[opc@uek8-vm ~]$ lsmod | grep 8021q [opc@uek8-vm ~]$ sudo modprobe 8021q [opc@uek8-vm ~]$ lsmod | grep 8021q 8021q 53248 0 garp 20480 1 8021q mrp 20480 1 8021q
Now, let’s try to load a module that’s not installed, such as tca6416-keypad
:
[opc@hamogala-vm-4 ~]$ sudo modprobe tca6416-keypad modprobe: FATAL: Module tca6416-keypad not found in directory /lib/modules/6.12.0-0.20.20.el9uek.x86_64, ensure the following package is installed: kernel-uek-modules-desktop-6.12.0-0.20.20.el9uek.x86_64
As shown, the updated modprobe
is now aware of the packaging structure and provides the user with a clear suggestion with regard to the required package to install, kernel-uek-modules-desktop
, which contains the tca6416-keypad
module.
Sample script to harden the system
Putting everything together, it is now possible to identify packages which can be removed for a given system as they do not provide any module that is actively in use.
Warning: Example Script Only
The following script is a simplified example and should not be used in production without thorough testing and validation. The script is intended to illustrate the basic concept of identifying kernel module packages with no loaded modules, but might not be comprehensive or correct in all scenarios.
#!/bin/bash # Sample script only kernel_version="$(uname -r)" module_mapping="/lib/modules/${kernel_version}/modules.packages" kernel_subpackages="$(cut -d' ' -f2 "${module_mapping}" | sort -u)" loaded_modules="$(lsmod | tail -n +2 | cut -d' ' -f1)" echo "Kernel module RPMs with no loaded modules for kernel version ${kernel_version}:" echo rv=0 for rpm in ${kernel_subpackages}; do num_loaded="$(grep "$rpm" "${module_mapping}" | cut -d' ' -f1 | grep -c -x -f <(echo "$loaded_modules"))" if [[ $num_loaded -eq 0 ]]; then echo " $rpm" rv=$(( rv + 1 )) fi done if [[ $rv -eq 0 ]]; then echo echo " No kernel module RPMs with no loaded modules found." echo else echo echo "${rv} kernel module RPMs may be removed." echo fi exit ${rv}
And a sample output from the script might look something such as this:
Kernel module RPMs with no loaded modules for kernel version 6.12.0-0.20.20.el9uek.x86_64: kernel-uek-modules-6.12.0-0.20.20.el9uek.x86_64 kernel-uek-modules-deprecated-6.12.0-0.20.20.el9uek.x86_64 kernel-uek-modules-extra-6.12.0-0.20.20.el9uek.x86_64 kernel-uek-modules-extra-netfilter-6.12.0-0.20.20.el9uek.x86_64 kernel-uek-modules-usb-6.12.0-0.20.20.el9uek.x86_64 kernel-uek-modules-wireless-6.12.0-0.20.20.el9uek.x86_64 6 kernel module RPMs may be removed.
Conclusion
In summary, the new packaging model for UEK 8 provides a more modular approach to manage linux kernel modules on a system, giving users greater control and flexibility over their system configuration, while helping users to optimize their systems for specific use cases.