% Uncomment "handout" mode for final PDF sharing
% \documentclass[handout,aspectratio=169]{beamer}
\documentclass[aspectratio=169]{beamer}

% Theme
\usetheme{RootCommit}

% Packages
\usepackage{graphicx} % For including images
\usepackage{hyperref} % For clickable links

% Title page details
\title{Linux Kernel Hardening with the Yocto Project}
\subtitle{Embedded World 2026}
\author{Michael Opdenacker}
\institute{Root Commit}
\date{Mar. 10, 2026}

\begin{document}

% Title Slide
\begin{frame}
    \titlepage
    \centering
    \includegraphics[height=0.16\textheight]{graphics/embedded-world-logo.jpg}
    \hfill
    \includegraphics[width=0.2\textwidth]{svg/rootcommit.pdf}
    \vfill
	\tiny{\copyright{} 2024-\the\year{} Root Commit. Licensed under CC BY-SA 4.0.}
\end{frame}

\begin{frame}{Michael Opdenacker}
\small
Embedded Linux consultant and trainer
\begin{columns}
\column{0.6\textwidth}
\footnotesize
\begin{itemize}
	\item \url{https://rootcommit.com/about/michael-opdenacker/} 
	\item Former founder of \href{https://bootlin.com}{Bootlin}
	\item New founder of \href{https://rootcommit.com}{Root Commit}
        \item Free Software enthusiast and advocate\\
	      (member of April.org) \\
        \includegraphics[height=0.2\textheight]{svg/april-logo.pdf}
\end{itemize}
\column{0.4\textwidth}
    \includegraphics[width=\textwidth]{graphics/michael-opdenacker-webcam.jpg}
\end{columns}
\end{frame}

\begin{frame}{What I Do For a Living --- What's Funding This Work}
\begin{columns}[t]
\footnotesize
\column{0.4\textwidth}
Consulting and engineering work
\begin{itemize}
\item Yocto Project\\
      System implementation, porting to new versions, new features
\item Linux Kernel\\
      Driver development, board bring-up, debugging
\item Embedded Linux\\
      Boot time, bug fixing, security and other optimizations
\end{itemize}
\begin{center}
\includegraphics[height=0.3\textheight]{graphics/soldering-penguin.png}
\end{center}
\column{0.6\textwidth}
Training --- \url{https://rootcommit.com/training}
\begin{itemize}
\item Yocto Project and OpenEmbedded --- Free Materials!
\item Linux kernel, board support, driver development\\
      Free Materials after next course!\\
\item Embedded Linux\\
\item Linux Boot Time Reduction\\
\end{itemize}
What's special: focus on practical activities, interactivity and
learning techniques. At the heart of the community!
\begin{center}
\includegraphics[height=0.3\textheight]{graphics/penguin-teaching.png}
\end{center}
\end{columns}
\end{frame}

\section{Kernel Hardening}

\begin{frame}{Protecting the Kernel}
\begin{columns}
\footnotesize
\column{0.28\textwidth}
\begin{itemize}
\item The kernel is the cornerstone and stronghold of a Linux based system.
\item It provides pretty good security by default, but there are developer friendly settings that are very attacker friendly too!
\item If the kernel is compromised, there is almost no limit to what an attacker can do.
\end{itemize}
\column{0.38\textwidth}
There are two main types of techniques to make your kernel harder to compromise:
\begin{itemize}
\item Reducing the attack surface
	\begin{itemize}
		\footnotesize
		\item Only keep the features and drivers needed in your system
		\item Good fit for dedicated embedded systems anyway
		\item Also helps to boot faster \emoji{wink}
	\end{itemize}
\item Using kernel hardening features
	\begin{itemize}
		\footnotesize
		\item Features making it harder to exploit unknown or future vulnerabilities
		\item Developed through the \href{https://www.kernel.org/doc/html/latest/security/self-protection.html}{Kernel Self-Protection} project. 
	\end{itemize}
\end{itemize}
\column{0.28\textwidth}
	\includegraphics[height=0.8\textheight]{graphics/penguin-defending-castle.png}
\end{columns}
\end{frame}

\subsection{Project Setup}

\begin{frame}{Production and Development Images}
\begin{columns}
\column{0.7\textwidth}
Prepare for production early during development
\begin{itemize}
\item Maintain a production image alongside the development one
\item Development settings isolated from the start \\
      from the production one
\item Less risk of forgetting debugging features \\
      in the production image
\end{itemize}
\column{0.3\textwidth}
\includegraphics[height=0.8\textheight]{svg/prod-and-dev-images.excalidraw.pdf}
\end{columns}
\end{frame}

\begin{frame}{Need for Production Test Image}
\begin{columns}
\column{0.5\textwidth}
\small
At this stage, we need some tools to test the production image
\begin{itemize}
\item Don't want to put them in the development image, will get false positives
      with development tools and features.
\item Don't want to leave them in the production image, could be used to reveal
      weak spots. They may also pull unwanted dependencies.
\item Solution: create a third "Production test" image.
\end{itemize}
\column{0.5\textwidth}
\includegraphics[height=0.8\textheight]{svg/prod-test-prod-and-dev-images.excalidraw.pdf}
\end{columns}
\end{frame}

\begin{frame}{Choose Your Kernel Carefully}
\begin{columns}
\column{0.7\textwidth}
\begin{itemize}
\item An {\bf LTS kernel} from \href{https://kernel.org}{kernel.org} is the best
      solution to get kernel updates quickly
\item {\bf linux-yocto} is pretty well supported, if you can wait a few weeks for updates.
\item {\bf Vendor kernels} support your hardware well, but they are not meant to
      include vulnerability fixes in a timely fashion. They can also be very outdated.
\end{itemize}
\column{0.3\textwidth}
\includegraphics[height=0.8\textheight]{graphics/penguin-bride.png}
\end{columns}
\end{frame}

\begin{frame}[fragile]{Enable vulnerability checking}
\begin{itemize}
\item Add this to \code{conf/local.conf}:
\begin{minted}[fontsize=\small]{sh}
INHERIT += "cve-check"
\end{minted}
\item This will add a CVE task to the recipes you're building
\item You may also want to ignore CVEs that are irrelevant to Poky and OE-core:
\begin{minted}[fontsize=\small]{sh}
include conf/distro/include/cve-extra-exclusions.inc
\end{minted}
\item To speed up NVD database downloads, request a unique key (\yoctovar{NVDCVE\_API\_KEY})\\
      \code{NVDCVE\_API\_KEY = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"}
\item Then, \code{bitbake} your regular image,\\
      and the checks will be run (without running the other tasks if not necessary)
\item You can also run checks on specific recipes:
\begin{minted}[fontsize=\small]{sh}
$ bitbake -c cve_check linux-yocto
\end{minted}
\end{itemize}
\end{frame}

\subsection{Detect Hardening Opportunities}

\begin{frame}[fragile]{Kernel Hardening}
\begin{columns}
\column{0.7\textwidth}
\footnotesize
\code{kernel-hardening-checker} from Alexander Popov
\begin{itemize}
\item \url{https://github.com/a13xp0p0v/kernel-hardening-checker}
\item Introduced only in Walnascar (\code{meta-oe})
\item Reports all the kernel configuration and command line settings which
      could be changed to harden the running kernel.
\item My contributions:
      \begin{itemize}
      \footnotesize
      \item Updated \code{meta-oe} to support version 0.6.10.2 (many recent changes),
            supporting a \code{-a} option and the RISC-V architecture (\href{https://git.openembedded.org/meta-openembedded/commit/?id=5ae3536204ba3764b03647ab75169ee65ca43531}{link})
      \item Backported to Scarthgap too. 
      \end{itemize}
\end{itemize}
\begin{block}{\footnotesize recipes-core/images/image-prod-test.bb}
\begin{verbatim}
IMAGE_INSTALL += "kernel-hardening-checker"
\end{verbatim}
\end{block}
\column{0.3\textwidth}
\includegraphics[height=0.8\textheight]{graphics/kernel-hardening.png}
\end{columns}
\end{frame}

\begin{frame}{\code{kernel-hardening-checker} example output}
\includegraphics[height=0.8\textheight]{graphics/kernel-hardening-checker-start.png}
{\huge ...}
\includegraphics[height=0.8\textheight]{graphics/kernel-hardening-checker-end.png}
\end{frame}

\begin{frame}[fragile]{Using \code{kernel-hardening-checker}}
\small
Try it on your PC!
\begin{itemize}
\item Clone the repository:
\begin{block}{}
\begin{minted}{sh}
$ git clone https://github.com/a13xp0p0v/kernel-hardening-checker.git
\end{minted}
\end{block}
\item Run it directly from the repository:
\begin{block}{}
\begin{minted}{sh}
$ /path/to/kernel-hardening/checker/bin/kernel-hardening-checker -a
\end{minted}
\end{block}
\end{itemize}
Run it on the embedded target:
\begin{block}{}
\begin{minted}{sh}
$ kernel-hardening-checker -a
\end{minted}
\end{block}
\end{frame}

\begin{frame}[fragile]{Lynis}
\begin{columns}
\column{0.8\textwidth}
\footnotesize
Lynis (\url{https://cisofy.com/lynis/})
\begin{itemize}
\item Very exhaustive checker for a very wide series of system security checks
\item This also includes networking and kernel checks
\item Primarily for PC distros but gives you tons of relevant ideas for hardening your OS
\item Available in the \code{meta-security} layer
\item Add it to your build:
\begin{block}{}
\begin{minted}{sh}
IMAGE_INSTALL += "lynis"
\end{minted}
\end{block}
\item Run it on your board:
\begin{block}{}
\begin{minted}{sh}
$ lynis audit system
\end{minted}
\end{block}
\end{itemize}
\column{0.2\textwidth}
\includegraphics[height=0.8\textheight]{graphics/lynis-screenshot.png}\\
\verytiny Output of \code{lynis audit system} on BeagleBone Black.
\end{columns}
\end{frame}

\begin{frame}{Kernel Hardening Notes}
\begin{columns}
\column{0.7\textwidth}
\footnotesize
\begin{itemize}
\item Kernel configuration: remove unnecessary features
      \begin{itemize}
      \footnotesize
      \item This reduces the attack surface, and boot time too!
      \item Yocto stores kernel modules in separate packages. \\
	    This helps to identify unnecessary ones!
      \end{itemize}
\item See \kdoc{security/self-protection} (kernel documentation) for details about kernel protection techniques.
\end{itemize}
\column{0.3\textwidth}
\includegraphics[height=0.8\textheight]{graphics/kernel-self-protection-doc.png}
\end{columns}
\end{frame}

\subsection{Implement Hardening}

\begin{frame}[fragile]{Modify Kernel Configuration Settings}
\footnotesize
\begin{columns}
\column{0.48\textwidth}
Using config fragments
\begin{itemize}
\item Possible for recipes inheriting the \code{linux-yocto} class
\item Convenient to manage settings separately
\item But adds impredictibility in case of settings
\end{itemize}
\begin{block}{\footnotesize \code{my-linux.bb}}
\begin{minted}{sh}
SRC_URI += " \
	file://kallsyms.cfg \
	file://randstruct-full.cfg \
	file://io-strict-devmem.cfg \
"
\end{minted}
\end{block}
\begin{block}{\footnotesize \code{io-strict-devmem.cfg}}
\begin{minted}{sh}
CONFIG_DEVMEM=y
CONFIG_IO_STRICT_DEVMEM=y
\end{minted}
\end{block}
\column{0.48\textwidth}
Using one complete configuration file
\begin{itemize}
\item Guaranteed to work as intended \\
      No issues because of conflicting parameters
\item Can be updated easily:\\
      \code{bitbake -c menuconfig linux-yocto} \\
      \code{bitbake -c savedefconfig linux-yocto}
\end{itemize}
\begin{block}{\footnotesize \code{my-linux.bb}}
\begin{minted}{sh}
SRC_URI += "file://defconfig"
\end{minted}
\end{block}
\end{columns}
\end{frame}

\begin{frame}{Kernel Hardening --- How To Proceed?}
\begin{itemize}
\item First apply configuration changes
      \begin{itemize}
      \item First remove unnecessary kernel features (time consuming!)
      \item Then follow applicable recommendations of \code{kernel-hardening-checker}
      \item Do it little by little, test at each iteration
      \item Keep track of all intermediate configurations (if rewinding is needed)
      \end{itemize}
\item Then tune the remaining kernel command line and {\em sysctl} settings \\
      Some are no longer relevant after kernel configuration changes
\end{itemize}
\end{frame}

\begin{frame}{Selected Kernel Hardening Settings (1)}
\begin{columns}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_FORTIFY_SOURCE.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_KFENCE.png}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_ARM_DEBUG_WX.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_HARDENED_USERCOPY.png}
\end{columns}
\end{frame}

\begin{frame}{Selected Kernel Hardening Settings (2)}
\begin{columns}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_FTRACE.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_KPROBES.png}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_KALLSYMS.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_KEXEC.png}
\end{columns}
\end{frame}

\begin{frame}{Selected Kernel Hardening Settings (3)}
\begin{columns}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_KSTACK_ERASE.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_COMPAT_BRK.png}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_COREDUMP.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_BLK_DEV_WRITE_MOUNTED.png}
\end{columns}
\end{frame}

\begin{frame}{Selected Kernel Hardening Settings (4)}
\begin{columns}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_MODULE_SIG_ALL.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_MODULE_SIG_FORCE.png}
\column{0.48\textwidth}
\includegraphics[width=\textwidth]{graphics/CONFIG_STRICT_DEVMEM.png}
\includegraphics[width=\textwidth]{graphics/CONFIG_IO_STRICT_DEVMEM.png}
\end{columns}
\tiny More such settings: \url{https://gitlab.com/rootcommit/yocto-kernel-hardening/-/tree/main/graphics/more-kconfig}
\end{frame}

\begin{frame}{Signing Kernel Modules}
\begin{itemize}
\item Module signing is automatic with \kconfig{CONFIG\_MODULE\_SIG\_ALL}. \\
      Also turn on \kconfig{CONFIG\_MODULE\_SIG\_FORCE}.
\item The signing key is generated on the fly and the public key is built into the kernel.
\item Not necessary to keep the private key. 
\item Still possible to use your own keys. Yocto can help you: \\ 
      \url{https://ejaaskel.dev/yocto-hardening-kernel-module-signing/}
\end{itemize}
See kernel documentation for details: \kdoc{admin-guide/module-signing} 
\end{frame}

\begin{frame}[fragile]{Modifying the Kernel Command Line}
\begin{columns}
\column{0.48\textwidth}
\footnotesize
Not completely trivial!
\begin{itemize}
\item No universal way to change the default command line
      (check the bootloader recipes).
\item However, you can always add parameters to the command line
	through the kernel {\em bootconfig} mechanism.
\end{itemize}
See kernel documentation: \kdoc{admin-guide/bootconfig}
\column{0.48\textwidth}
\tiny
\begin{block}{\tiny \code{linux-stable\_\%.bbappend}}
\begin{minted}{sh}
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
KBUILD_DEFCONFIG = ""

do_configure:prepend() {
    install -m 0644 ${UNPACKDIR}/cmdline.bootconfig ${S}/
}

SRC_URI += " \
    file://defconfig \
    file://cmdline.bootconfig \
"
\end{minted}
\end{block}

\begin{block}{\tiny \code{defconfig}}
\begin{minted}{kconfig}
...
CONFIG_BOOT_CONFIG=y
CONFIG_BOOT_CONFIG_EMBED=y
CONFIG_BOOT_CONFIG_EMBED_FILE="cmdline.bootconfig"
\end{minted}
\end{block}

\begin{block}{\tiny \code{cmdline.bootconfig}}
\begin{minted}{ini}
kernel {
	page_alloc.shuffle=1
	hash_pointers=always
	nosmt
}
\end{minted}
\end{block}
\end{columns}
\end{frame}

\begin{frame}[fragile]{Modifying {\em sysctl} Parameters}
\begin{columns}
\column{0.63\textwidth}
\tiny
\begin{block}{\tiny \code{recipes-core/sysctl/sysctl-config.bb}}
\begin{minted}{sh}
SUMMARY = "Custom sysctl configuration for kernel hardening"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda..."

SRC_URI = "file://99-kernel-hardening.conf"

do_install() {
    install -Dm 0644 ${UNPACKDIR}/99-kernel-hardening.conf \
	${D}${sysconfdir}/sysctl.d/99-kernel-hardening.conf
}

FILES:${PN} += "${sysconfdir}/sysctl.d/99-kernel-hardening.conf"
\end{minted}
\end{block}
\column{0.33\textwidth}
\tiny
\begin{block}{\tiny \code{files/99-kernel-hardening.conf}}
\begin{minted}{ini}
# Kernel hardening settings
kernel.oops_limit = 100
kernel.warn_limit = 100
kernel.perf_event_paranoid = 3
kernel.kptr_restrict = 2
user.max_user_namespaces = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
fs.protected_fifos = 2
fs.protected_regular = 2
kernel.yama.ptrace_scope = 3
\end{minted}
\end{block}
\end{columns}
\end{frame}

\begin{frame}{Kernel Hardening: Notes}
\begin{itemize}
\item Many default kernel options are developer friendly, not security friendy.
\item You don't want many such options in a production embedded system. 
\item Some hardening features are meant to find issues in kernel code, \\
      but have a significant performance cost. \\
      You may remove them in production systems after running robustness tests.
\item Not all recommended security features are relevant:
      \begin{itemize}
      \item Some of them may not be available on your hardware
      \item You may not need them in your specific system.
      \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}{Demo: Kernel Hardening on Beagle Bone Black}
\begin{columns}
\column{0.7\textwidth}
\begin{itemize}
\item The only hardware board officially supported by Yocto (\code{meta-yocto-bsp} layer)
\item Before hardening:
      \begin{itemize}
      \item Compressed kernel size: 5.5 MB
      \item Number of OK: 159 
      \item Number of FAIL: 125
      \end{itemize}
\item After hardening:
      \begin{itemize}
	      \item Compressed kernel size: 4.7 MB \\
		    Note: minimal effort to reduce kernel size
      \item Number of OK: 278
      \item Number of FAIL: 6 \emoji{tada}
      \only<2>{\newline which are actually OK for me \emoji{wink}}
      \end{itemize}
\end{itemize}
\column{0.3\textwidth}
\includegraphics[width=\textwidth]{graphics/beagleboneblack.png}
\pause
\end{columns}
\end{frame}

\begin{frame}{Final Report}
\includegraphics[width=\textwidth]{svg/ultimate-report.pdf}
\end{frame}

\section{Wrapping Up}

\begin{frame}{What To Remember}
\begin{itemize}
\item \code{kernel-hardening-checker} from Alex Popov is your best friend. \\
	Find it in the \code{meta-oe} layer (\code{meta-openembedded} repository)
\item Default kernel configurations are developer friendly, not secure enough
\item There is lot of functionality you don't need in an embedded system \\
      This helps to reduce the attack surface
\item Pretty easy to increase security without sacrificing functionality \\
      and performance (not substantially)
\item Don't apply recommendations blindly
\item This protects against future vulnerabilities. \\
      But don't forget to fix known ones!
\end{itemize}
\end{frame}

\begin{frame}{Useful Resources}
\begin{columns}
\footnotesize
\column{0.6\textwidth}
\begin{itemize}
\item Michael Opdenacker --- Securing Yocto Built Systems \\
	\url{https://rootcommit.com/pub/conferences/2025/elce/yocto-security/yocto-security.pdf}
\item Root Commit Blog --- Yocto Security: Kernel Hardening \\
	\url{https://rootcommit.com/2025/yocto-security-kernel-hardening/}
\item Root Commit's Yocto Project training course \\
	\url{https://rootcommit.com/training/yocto}
\item Esa Jääskelä --- Yocto Hardening \\
      Series of blog posts about many aspects of the topic\\
      Fun and exhaustive! \\
      \url{https://ejaaskel.dev/yocto-hardening/}
\end{itemize}
\column{0.4\textwidth}
%\includegraphics[height=0.8\textheight]{graphics/penguin-books.png}
\includegraphics[height=0.7\textheight]{graphics/crushingwave_2048x2048.jpg}\\
\tiny Darknet Diaries podcast shop: \url{https://shop.darknetdiaries.com}
\end{columns}
\end{frame}

\begin{frame}{For Further Details... \emoji{wink}}
\begin{columns}
\column{0.63\textwidth}
	\includegraphics[width=\textwidth]{graphics/yocto-booth.jpg}
\column{0.3\textwidth}
\small Booth 4-648
\begin{itemize}
	\item Have Yocto goodies: coffee \emoji{coffee}, cookies \emoji{cookie}
\item Our best swag: our smiles \emoji{grinning} 
\item Come and see how welcoming the Yocto community is.
\end{itemize}
\end{columns}
\end{frame}

\usebackgroundtemplate{\includegraphics[width=\paperwidth,height=\paperheight]{svg/yocto-booth-background.pdf}}

\begin{frame}{Thank you}
\begin{columns}
\column{0.7\textwidth}
\huge Questions? Comments? 
\vfill
\footnotesize
\begin{itemize}
\item mo@rootcommit.com
\item \includegraphics[height=1em]{svg/mastodon-icon.pdf} \url{https://fosstodon.org/@MichaelOpdenacker}
\item XMPP: omichael@conversations.im
\item Signal: rootcommit.01
\end{itemize}
\vfill
\begin{itemize}
\item Slides available under the CC-By-SA 4.0 license\\
\url{https://rootcommit.com/pub/conferences/2026/embedded-world/yocto-kernel-hardening/}
\item Sources (\LaTeX):\\
\url{https://gitlab.com/rootcommit/yocto-kernel-hardening/}
\item Code used in this demo:\\
\url{https://gitlab.com/rootcommit/meta-kernel-hardening-demo}
\end{itemize}
\column{0.3\textwidth}
\includegraphics[width=\textwidth]{svg/qr.pdf}
\end{columns}
\end{frame}

\end{document}
