|
|
Log in / Subscribe / Register

Shielding running kernels against exploits with BPF

By Daroc Alden
July 13, 2026

LSFMM+BPF

Cisco has some unusual challenges when it comes to deploying security patches across the company's many devices running custom kernels. John Fastabend spoke about his work preventing exploits with BPF at the 2026 Linux Storage, Filesystem, Memory-Management, and BPF Summit. The technique could substantially reduce the time necessary to respond to kernel vulnerabilities, but it will not be fully effective unless more hooks are added to the kernel.

Network switches encompass a big range of hardware, Fastabend began. From small single-rack systems all of the way through huge high-speed devices. Each of Cisco's supported platforms has its own kernel team that builds custom kernels using Yocto. At any given time, those teams are supporting a large number of different kernels — mostly stable kernels, fortunately, he added. All of these widely deployed, internet-connected devices with custom kernels make tempting targets for attackers.

[John Fastabend]

Cisco publishes security updates, obviously, but it takes time to identify a problem, write a fix, create a new build, test it, provide it to customers, and then let switches update, especially because rebooting switches can cause network disruptions. Those disruptions require clients to plan and manage downtime, and the whole process can take months from discovery to patching the last vulnerable systems. The goal of Fastabend's work has been to use BPF to observe attacks in real time, and then allow them to be addressed on demand, without rebooting. Ideally, the whole process would take only minutes, he said. "We won't be there for a while, but that would be the dream."

Tetragon, the open-source BPF-based monitoring and enforcement tool, is used to collect "lots of data" about running systems. At any time, the monitoring infrastructure on a switch can show which programs ran at which times, and which network connections they made. That data is stored in a time-series database. Tetragon does currently depend on a user-space agent to remain operational, but Fastabend and his colleagues have been working toward making the BPF components survive even if an attacker manages to kill the user-space agent. When a new CVE is discovered, he explained, he wants to be able to check against that database to find out whether it was ever exploited. The data can also be used to see the symptoms of an attack, such as data exfiltration or connections to command-and-control servers.

Once an exploit is identified, it can be blocked directly from BPF. If a particular system call is necessary to trigger the exploit, BPF can override the return value of the system call to refuse the operation. It is also possible to use tracepoints to verify that the arguments to internal kernel functions are correct. Fastabend's team uses both uprobes and kprobes for that. Those probes don't reliably allow changing return values, however, so Linux security-module (LSM) hooks are used for that.

Andrii Nakryiko asked how many events per second were being checked and potentially intercepted by this design. The routing of network packets is mostly done by dedicated hardware, Fastabend explained, so the kernel only needs to manage control-plane traffic and user-space applications. Overall, there are only hundreds or thousands of events per second, not billions, even if the switch is moving billions of packets.

One complication is that Fastabend's team wants to use probes to operate on inlined functions as well. That is possible by using debugging symbols and setting a probe at a raw offset. Cisco has a build farm that is used to produce all of its kernel packages, he explained. The build machines save the build IDs and debugging information from all of the builds, including both BTF and normal debugging symbols. That information is used to debug customer problems, but also to make it possible to write live kernel patches or BPF programs that are specific to the structure of deployed kernels.

Jakub Sitnicki noted that he has experienced a problem attaching probes to functions that are partially inlined, since information on where those functions have been inlined is not presently included in the kernel's BTF, but the problem is being worked on. Alan Maguire said that the topic would be covered in one of the sessions he had proposed for the next day of the conference.

Blocking exploits

Fastabend then showed an example of a BPF program that could be used to block the effects of the recent copy fail vulnerability. The program just made the splice() system call return an error when called in a way that would trigger the bug. His team calls such BPF programs "shields". Something like this would technically be possible to do with a normal kernel live patch, he admitted, but Cisco has so many concurrent product lines, with many different stable kernels running on them, that it would require a huge investment of developer time to patch them all. With BPF, the same program can typically run across all of the supported kernels — it just needs to be written once, and then automatically tested on each kernel to make sure it doesn't break anything.

BPF shields are great when they work, but there are some occasional hiccups. Often, Fastabend's team will find a CVE that doesn't have any relevant hooks in the affected kernel subsystem to build a shield around, he said. Most recently, there was an exploitable use-after-free bug that simply didn't have anywhere convenient to hook close to the source of the problem. The team eventually settled on hooking the system call that could lead to triggering the bug, but it made for more complex code.

Therefore, the main change that Fastabend would like to see in the kernel to support efforts like this is a more inclusive policy for ALLOW_ERROR_INJECTION(), the macro that is used to mark functions that can be subjected to the kernel's error-injection framework. While normally used for testing, the framework allows kernel programmers to override the return values of internal functions with custom BPF programs, which is a neat match for Fastabend's use case. Unfortunately, only a subset of kernel functions have been marked for use with error-injection. Ideally, he would like to be able to use BPF to modify the return value of any function that returns an integer which is compared to zero and has that error propagated up the stack. There are plenty of functions that match this criterion, he said. There should be LSM hooks for all of these, he said. Fastabend asked whether those functions could easily be made hookable from BPF.

Nakryiko thought that the complexity of error-handling code would make any change like that a manual process. Alexei Starovoitov suggested that it should be possible to do automatically for Rust code, given that the compiler-generated cleanup logic in Rust code has a predictable structure. For C code, he suggested asking the people submitting vulnerability reports to introduce a relevant LSM hook as well. I suggested using Coccinelle to make the change.

If it did end up being a manual process, the most important place to target would be the kernel's netlink code, Fastabend thought. For whatever reason, his team sees a lot of attacks targeting that area of the kernel.

The technique of hooking internal kernel functions as a protection against vulnerabilities is certainly useful to other users of the Linux kernel as well. The shield he showed was only a handful of lines of code, and it is easy to see how, with sufficient coverage of the kernel, that kind of simple fix would provide a way for companies or distributions to deploy vulnerability mitigations across multiple kernel versions with much less hassle. That said, the work of adding LSM hooks to the relevant areas will be a large change, and may take some time — if the LSM maintainers approve of the work at all.



to post comments

Tetragon security model ?

Posted Jul 13, 2026 15:51 UTC (Mon) by Lionel_Debroux (subscriber, #30014) [Link] (2 responses)

Tetragon immediately made me think about https://grsecurity.net/tetragone_a_lesson_in_security_fun... .
It's been 4 years since that post which described why Tetragon's security model couldn't work, which brings the question: did things change since then, considering that from what I can gather, the usage of same privilege level technologies (BPF, kprobes, uprobes, LSM hooks) remains ?

Tetragon security model ?

Posted Jul 13, 2026 16:56 UTC (Mon) by geofft (subscriber, #59789) [Link]

The LWN writeup is phrased to say they're using Tetragon for detection, not for mitigation. That is, they're trying to find signs that a vulnerability was invoked or an unwanted privilege escalation occurred, but they're not expecting the compromised kernel to be able to fully defend itself against the exploit. Once they know about a vulnerability, the system that this article is about is used to prevent further exploitation on other systems in the first place, which is the approach the grsec article recommends.

I suppose it's possible that a sufficiently skilled exploit could turn off reporting, but I think this basically turns into a race condition - whether the malicious code can kill the reporting codepath before it manages to fire a packet off - and this is now biased in favor of the defender. Race conditions are not a great answer when trying to prevent exploitation, since a single successful exploit is a win for the attacker. But they're a much better answer if you're simply trying to detect it, since a single unsuccessful exploit is a win for the defender, who now knows they have something to respond to. So, if the exploit is some non-deterministic thing that is mostly stymied by ASLR, then a single report of malicious code having run and failed to secure a foothold is enough.

Tetragon security model ?

Posted Jul 14, 2026 8:57 UTC (Tue) by bjackman (subscriber, #109548) [Link]

The important detail here is: if the bypassable security mechanism is built by grsecurity then "yes it's not bulletproof but it increases the cost of attacks and serves as a tripwire". If someone else builds it then "look, this can be bypassed therefore it's useless".

Anyone who has actually done real-world security work can tell you that post-exploit security features are valuable in practice even if they are useless in theory.

Reinventing live patching?

Posted Jul 14, 2026 5:34 UTC (Tue) by siddh (subscriber, #169663) [Link] (2 responses)

I'm biased obviously, but this is already solved by Ksplice and friends. And one can't always error out a function IMO, extreme example being the recent Arm TLB racing exploit.

Reinventing live patching?

Posted Jul 14, 2026 13:17 UTC (Tue) by zhalas (subscriber, #114013) [Link] (1 responses)

As far as I understand, they want to use it as a temporary mitigation. They claim that live patching is not viable for them in the short term due to the huge number of kernel variations they have.
I'm not sure, though, how they envision validating the temporary mitigation. I mean, blocking syscalls is easy, but validating that the product works across such a variety - less so.

Reinventing live patching?

Posted Jul 14, 2026 13:47 UTC (Tue) by siddh (subscriber, #169663) [Link]

I agree. If some old kernel uses the error return value for something or the function logic is different, then the "mitigation" might not suffice alone. So you end up having to test for each kernel, and at that point I'm not sure if the "temporary" fix is worth it.

Variations are a non-issue technically, so it seems the claim is more due to a business decision to not have a livepatching solution.

Also, temporary is an alias for permanent in many settings :-P

Cisco tech debt

Posted Jul 14, 2026 15:42 UTC (Tue) by raven667 (subscriber, #5198) [Link]

> Each of Cisco's supported platforms has its own kernel team that builds custom kernels using Yocto.

> His team calls such BPF programs "shields". Something like this would technically be possible to do with a normal kernel live patch, he admitted, but Cisco has so many concurrent product lines, with many different stable kernels running on them, that it would require a huge investment of developer time to patch them all. With BPF, the same program can typically run across all of the supported kernels

I'm sure Fastabend knows this all too well but as a customer with passing familiarity with some of their products who can see the result of their development practices, they just aren't organized as a software engineering firm, even though much of what they rely on is software as hardware designs are commodified by the likes of Broadcom. Every hardware team forking the entire software stack for each product line trades delivery speed for maintainability, no one has to coordinate or communicate and can just hack away to make things work, but also enforcing any company-wide quality standards becomes impossible. Sometimes you notice the seams when details of functionality are different or missing across hardware generations or product lines even when they run the "same" OS, or in things like watching them boot where you can see a bunch of stuff which looks ad-hoc because it just needed to work *enough* rather than being a congruent part of an engineered system. This effort is trying to be an improvement, but it's yet another ad-hoc layer to deal with the fact that they can't consolidate to a maintainable handful of kernels even when it all runs Linux. You would think that one could build as many different hardware configs as were needed out of the same source tree (eg the kernel.org kernel can be built unmodified for hundreds/thousands of different device platforms), both for the kernel and for userspace, but alas no.


Copyright © 2026, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds