iTranslated by AI
My First Patch Submission to the Linux Kernel
I submitted a patch to the Linux kernel as a result of my graduate research. In this article, I will explain the technical background and the details of my contribution.
Technical Background
In this section, I will explain the technical background related to my contribution.
The Linux Kernel (OS)
In a nutshell, the role of an OS is "resource management." For example:
- Computing Resources: Allocating CPU time equally among multiple processes.
- Memory Resources: Allocating RAM to processes / Saving files to HDD.
- Network Resources: Sending data received from processes to the network.
By entrusting these resource management tasks to the OS, we can manipulate files without worrying whether the storage is an HDD or an SSD, and use the Internet without being conscious of TCP/IP or Ethernet.
In recent years, there have been many demands for adding features to the OS, such as security and monitoring in distributed systems. However, because stability and safety are required for an OS, adding new features directly to it is a difficult and time-consuming task. This is where eBPF comes in, allowing features to be added later as plugins without modifying the OS core.
eBPF (extended Berkeley Packet Filter)
eBPF is a mechanism that allows for safely extending Linux kernel functionality. Although it contains "packet filter" in its name, this is purely historical; in modern contexts, it is far removed from being a mere filter.
There have been several ways to extend OS functionality:
- Applying patches to the OS source code itself.
- Using kernel modules.
The straightforward method is 1, but the massive size of the Linux codebase and the effort required for debugging are significant issues. Method 2 is a plugin approach that has been used for many years, but if the module itself has a bug, it could cause the entire OS to freeze. If this happens, the only way to recover is to force a reboot of the machine.
This is why eBPF was proposed. eBPF provides a sandbox environment inside the OS and runs plugin programs within it, preventing worst-case scenarios like an OS freeze even if the program itself has issues. How this sandbox environment is secured is the core of eBPF technology.
Verifier
eBPF ensures the safety of plugin programs by verifying them in advance. "Safety" here means:
- No illegal memory access.
- The program finishes in a realistic amount of time.
The eBPF verifier checks for these security issues by performing static analysis on the program. Specifically, it tracks and confirms the range of variable values and function calls across all code paths. The verifier rejects the loading of a program if it attempts to access memory outside the sandbox or if it detects potential infinite loops.
While the verifier's mechanism is powerful for ensuring safety, it imposes constraints on programming. For example, writing complex programs with many nested for-loops often leads to the verifier being unable to track variables, resulting in rejection. This characteristic is very inconvenient for tasks such as string comparison.
To address this, there is a mechanism to move parts of the program outside the verifier's scope.
KFunc
KFuncs are kernel functions that can be called from eBPF. The eBPF verifier checks the arguments' ranges and types for functions, but it does not verify the internal workings of the KFunc. Therefore, by defining string comparison functions as KFuncs, we can bypass the constraints of the verifier.
The Linux kernel pre-defines string comparison functions often used in eBPF as KFuncs. Examples of such functions are:
-
bpf_strcmp: Compares two strings. -
bpf_strcasecmp: Compares two strings (ignoring case). -
bpf_strstr: Searches for a substring within a string.
These functions are similar to those defined in the C standard library <string.h>, but they are tuned for eBPF, such as having internal limits on string length or being annotated so the verifier can validate the arguments.
Contribution Details
I added bpf_strncasecmp as a new Kfunc. The behavior of bpf_strcasecmp and bpf_str'n'casecmp is almost identical, but the latter compares only the first n characters of the provided strings. Examples of its operation are as follows:
-
bpf_strcasecmp("hello", "HELLO"): The two strings are equal. -
bpf_strcasecmp("hello", "HELLO WORLD"): The two strings are different. -
bpf_strncasecmp("hello", "HELLO WORLD", 5): The two strings are equal.
This function is useful when parsing HTTP headers in eBPF. HTTP headers are case-insensitive regarding keys. When parsing HTTP headers line by line, finding a specific key in a header requires a case-insensitive prefix match.
Impressions
Although it was my first time developing using a mailing list, I was impressed by how well the development environment was established. Mechanisms were in place for many developers to maintain the project in a distributed manner, such as scripts to retrieve people to include in the email CC, and automatic CI runs when specific prefixes were included in emails. I also felt that the latest technologies are being incorporated into Linux kernel development, as AI-based reviews using Claude were also introduced.
Additionally, it was impressive to receive feedback from reviewers regarding "consistency with other code." This is a principle that code with similar behavior should adopt a similar implementation. I believe that prioritizing consistent code over code that runs slightly faster is unique to an environment like the Linux kernel, where stability and safety are paramount.
Throughout this process, I learned a great deal about Linux kernel debugging, how to submit patches, and how to build maintainable systems.
Discussion