My Linux Kernel bug fixing program experience
Introduction
Hello everyone! I’m Suchit, a recent graduate from the National Institute of Technology Karnataka, Surathkal. My primary interests lie in systems programming, computer networks, and low-level programming, and recently, I’ve been diving deep into eBPF and its internals. I’m also passionate about open source, and I’m grateful that my open source journey began with contributions to the Linux kernel.
In this blog, I’ll be sharing my experience with the Linux Kernel Bug Fixing Program. I participated in the part-time program, which ran from March 2025 to August 2025. Although the beginning felt a bit overwhelming and I couldn’t fully focus on this program during the first 3–4 months, I successfully completed the requirement of submitting at least five patches upstream. I’d like to express my sincere gratitude to Shuah Khan for organizing this program and mentoring us throughout. In my view, this initiative does a wonderful job of encouraging newcomers to contribute to the Linux kernel and open source in general, kudos to Shuah and all the mentors for making it possible.
Why did I choose this program?
I’ve always been curious about how things work under the hood and how performance-critical components are built. The kinds of optimizations that go into low-level systems still fascinate me, and I couldn’t think of a better project than the Linux kernel to explore and learn about them. Earlier, I was a Windows user, but after switching to GNU/Linux (I use Arch, btw ;)), I found it impossible to go back. The freedom and flexibility that Linux provided were truly amazing, thanks to the countless contributors who have worked tirelessly to improve it without expecting anything in return. Over time, I began to feel that simply using this amazing software for free wasn’t enough. As a programmer, the best way I could give back was by contributing to the kernel itself, and that’s why I chose this program as my entry point into open source.
My Experience
At the beginning, I was completely clueless about where to start. The Linux kernel is a monolithic kernel, and its repository is massive, with multiple subsystems and over 40 million lines of code. I was particularly interested in the BPF and networking subsystems, so I began exploring them by reading blogs that explained their internals. At the same time, I went through the implementation directly to gain a deeper understanding and to observe the clever techniques used by kernel developers to achieve both performance and safety.
Reading through the code significantly improved my knowledge of C and compiler optimizations. For example, anyone who has learned C knows that to minimize the size of a struct due to alignment, fields are usually arranged in decreasing order of their sizes. However, in kernel code this convention isn’t always followed, as other trade-offs such as cache-line locality or maintaining ABI stability sometimes take precedence over size optimization.
Next, I wanted to move on to solving real bugs in the kernel. But I quickly realized that manually finding bugs is very difficult, and even testing changes can be more challenging than fixing the original problem. I faced this situation while working on one of my patches. The issue was that when changing the TX queue length, if updating the length of the corresponding qdiscs failed, we had to revert the partially updated qdiscs back to their old length. Sounds simple, right? But it wasn’t.
I implemented a straightforward solution and submitted it as a patch. However, I was unsure how to properly test it, and I suspected my approach might be flawed because I was calling the same function (the one prone to failure) to revert the qdiscs’ queue length to the old value when an update failed. Despite my doubts, I sent the patch to the mailing list to seek feedback. The maintainers and the original author were kind and they explained that the actual solution would indeed be more complex and echoed the concerns I had raised in my own description.
Now, I began looking at syzkaller bugs listed on its website and filtered out those related to the BPF and networking subsystems. But before that, I wanted to properly learn how to use syzkaller, and since I had set it up locally earlier, I revisited it. I compiled the latest version of the kernel and fuzzed it using syzkaller. It was quite rewarding to see it find bugs and warnings, even though most of them were already reported on the syzkaller dashboard. Still, it was exciting to watch it in action.
However, I wasn’t able to fix most of these issues, either because I wasn’t confident about the solution or because someone else had already posted a fix. This made me realize that my understanding at the time wasn’t enough to tackle subtle and complex bugs like race conditions. So, I shifted my focus to fixing simpler issues.
I started to search for “fixme” and “todo” comments in the codebase using the grep command. There were plenty of such comments, but many lacked proper context. I went through them regardless of the subsystem and eventually found some simple issues that I could actually fix.
During one of the office hours meetings, Shuah mentioned that uses of the strcpy() function should be replaced with safer alternatives, since strcpy() is deprecated in the kernel codebase. I found several such instances, but there was a catch: in many cases, the replacement wasn’t really necessary because memory was allocated correctly and the chances of overflow were minimal.
This raised an important question: if the code is already working as intended, should we really change it just for the sake of readability? I learned the answer from Greg Kroah-Hartman, a major Linux kernel developer who maintains the -stable branch, the staging subsystem, USB, and more. Although Greg wasn’t a mentor in this program, he often commented on patches to guide newcomers. I’m grateful for that, because his message was clear: “If the code is working properly, there’s no need to change it.” Because even small, seemingly harmless modifications like replacing strcpy() with an alternative can risk introducing regressions into the code. This experience taught me that not every change is a good change, sometimes restraint is just as important as writing code. It was a valuable lesson in understanding the philosophy of kernel development: stability and correctness always come first.
Patches that were accepted into mainline
Here’s the list of my patches that were accepted during the program with a short description about it. I’ve excluded patches that fixed minor typos and grammar errors, since these don’t count for the program’s minimum patch requirement. You can find all the patches that were accepted here.
- Patch 1: x86/cpu/intel: Fix the constant_tsc model check for Pentium 4 (Commit hash: 24963ae1b0b6596dc36e352c18593800056251d8)
* I discovered this issue while compiling the kernel with extra warning flags (make W=1 C=1). The fix itself was straightforward, but I initially made several mistakes in the patch formatting. One of the maintainers patiently reviewed my patch, pointed out the issues, and provided constructive feedback. This experience highlighted one of the aspects I really appreciate about Linux kernel development: maintainers care deeply not just about the code, but also about things like commit messages and changelogs. Every patch goes through rigorous review, with questions about design choices, performance implications, and other details. Only once the maintainers are fully convinced does a patch make it into mainline. - Patch 2: kconfig: lxdialog: replace strcpy() with strncpy() in inputbox.c (Commit hash: 5ac726653a1029a2eccba93bbe59e01fc9725828)
* In the Kconfig subsystem’s lxdialog code, I replaced an unsafe use of strcpy() with strncpy(). This improved safety by preventing possible buffer overflows in cases where string lengths could exceed expectations. - Patch 3: kconfig: lxdialog: replace strcpy with snprintf in print_autowrap
(Commit hash: 1918f983687aa73bf0e5bc73431898994fce35a8)
* In another part of the same lxdialog code, I replaced strcpy() with snprintf() to make the copying process both safer and more explicit. - Patch 4: net: stream: add description for sk_stream_write_space() (Commit hash: 8b7ab8eb52b51a7058edf0035e47b281f9fc9a19)
* I addressed a long-standing FIXME in the networking stack by adding a proper kernel-doc comment for the sk_stream_write_space() function. This improved documentation clarifies the function’s purpose and will help future developers working with the networking subsystem. What makes this patch especially fun is that the FIXME comment was written 21 years ago by Linus Torvalds himself and I was the one to fix it over two decades later! It’s a small reminder of just how vast and long-lived Linux development really is, with its 40+ million lines of code. - Patch 5: jfs: jfs_xtree: replace XT_GETPAGE macro with xt_getpage()
(Commit hash: 1014354cd8d40e81e9a6e9037a10ebfc0b656d27)
* This patch replaced an old macro with an inline function, xt_getpage(), in the JFS filesystem code. It had been marked with a TODO comment for quite some time, and I was lucky to spot it and implement the fix. This was also the first non-trivial patch of mine that got accepted into mainline.
Conclusion and Next Steps:
Firstly, I would like to thank Shuah once again for conducting this program and mentoring us throughout the program. Overall, this journey into Linux kernel development has been an incredibly rewarding experience. While I’ve highlighted a few of my accepted patches here, I submitted many more — some were accepted, some are still under review, and others were rejected. Each outcome taught me something valuable, whether it was about the kernel’s internals, the patch submission process, or simply how to write clearer commit messages. Contributing to such a large and mature codebase has been both humbling and motivating, and it has deepened my appreciation for the collaborative effort that powers the Linux kernel. I also enjoyed interacting with new people and exchanging ideas on the mailing lists.
This is just the beginning, and I’m excited to continue contributing and learning from the community. In particular, I would be focusing more on the BPF and networking subsystems and stay active on the mailing lists to grow further.
Open source is fun, long live the Linux kernel!