eBPF Threat Model
eBPF Threat Model
control-plane.io
Driving the Technical Direction and Vision
of eBPF
The eBPF Foundation focuses on advancing the state of the art for eBPF by directing
upstream development, promoting the use of the technology and its benefits, and
improving the security and robustness of eBPF as a whole.
Members
Platinum Silver
© controlplane 2024 2
Driving the Technical Direction and Vision of eBPF 2
Members 2
Introduction 4
Document Purpose 4
Scope 4
Document Structure 4
Background 6
eBPF Technical Overview 6
eBPF Helper Functions of Interest to Threat Actors 8
Data Flow Diagrams (DFDs) 9
High-Level eBPF DFD 9
DFDs for different eBPF use cases 9
Threat Model 12
Threat Model Scope 12
Attack trees 13
Confidentiality and Integrity 13
Availability 14
Evade Security Tooling 15
Mitigating Controls and Recommendations 17
Detailed Threats and Controls 20
Conclusions 27
Appendix 28
Kernel Changes of Note 28
References 29
© controlplane 2024 3
Introduction
Document Purpose
This document was commissioned by the eBPF Foundation to provide security
information and guidance to large enterprises using or looking to adopt
eBPF-based tools. The goal of the paper is to promote the security benefits of
eBPF over traditional tooling, whilst raising awareness of potential risks that could
arise in common use cases.
Scope
eBPF was originally created for the Linux Kernel, so this whitepaper assumes that
all compute instances are running Linux-based operating systems. eBPF
implementations outside of the Linux kernel are beyond the scope of this threat
model.
The pace of innovation and change in the eBPF ecosystem is rapid, therefore new
controls against some of the threats presented here may be developed in the
future. New eBPF developments can be followed via ebpf.io and ebpf.foundation,
and Linux kernel changes which have affected this document are recorded in the
Kernel changes of note appendix.
Document Structure
The Threat Modelling approach applied here is structured around Shostack’s four
questions:
1. What are we building? This involves understanding what eBPF is, and
how eBPF programs work.
2. What can go wrong? Following the definition of a simple, high-level
scenario in the Threat Model Scope, we develop attack trees to explore how
an attacker could utilise eBPF for nefarious purposes.
© controlplane 2024 4
3. What can we do about the things that can go wrong? Once a list of
threats has been established, inherent eBPF controls and end-user
recommendations are mapped against them.
4. Are we doing a good job? Finally, the threat model's outcomes are
reviewed to provide practical guidance for eBPF adopters.
In accordance with this blueprint, the rest of the paper is structured as follows:
© controlplane 2024 5
Background
eBPF is a technology that allows pre-analysed and validated programs to be run
in the Linux kernel or other privileged execution contexts. It is used to safely and
efficiently extend the capabilities of the kernel without requiring a change to
kernel source code, or loading kernel modules. The name “eBPF” was originally an
initialism, but as its usage and capabilities have expanded it is now a standalone
term.
eBPF enables tools to leverage low-level kernel access within security guardrails.
Its safety comes from the eBPF verifier (explained in eBPF Technical Overview),
Just-In-Time (JIT) compiler, and some automatic mitigations, and it also enables
more granular permission grants via capabilities. Due to these guardrails, eBPF is
proposed as the first option to consider over kernel modules or patches.
Creating eBPF code that conforms to the verifier can make some tasks more
difficult, but its Turing completeness enables its many use cases which are more
tightly secured than equivalent direct kernel manipulation. Many large
companies utilise eBPF as the safest method to write kernel-level tooling and
produce highly performant solutions: common use cases include performance
monitoring, observability, tracing, networking, and security detection and
enforcement.
eBPF programs are generally written in pseudo-C code or Rust and compiled into
eBPF bytecode1 which can then be run within the Linux Kernel. eBPF programs
are loaded into the kernel by a userspace program using the bpf() syscall,
commonly using a library such as libbpf (C) or ebpf-go (Go). When a program is
loaded, the bpf() syscall returns a file descriptor to the program being loaded.. The
program subsequently remains in memory until the file descriptor is closed. If a
process can obtain a file descriptor to an eBPF object, future operations on that
object are allowed.
eBPF programs are event-driven, and are run when the kernel or an application
passes a certain hook point. Pre-defined hooks include system calls, function
entry/exit, kernel tracepoints, network events, and several others. If a predefined
hook does not exist for a particular requirement, it is possible to create a kernel
probe (kprobe) or user probe (uprobe) to attach eBPF programs almost anywhere
in kernel or user applications.
1
Writing eBPF bytecode by hand is of a similar difficulty to hand-writing Assembly.
© controlplane 2024 6
Before the program can be attached to the appropriate hook, the program must
pass through the eBPF verifier, which confirms that the program is safe to run, for
example by checking that:
● The process loading the eBPF program holds the required capabilities
(privileges)
○ Unless unprivileged eBPF is enabled, only privileged processes can
load eBPF programs
● The program does not crash or otherwise harm the system
● The program always runs to completion (i.e. it does not sit in an infinite
loop)
eBPF programs are restricted to a fixed set of memory regions with a fixed-size
stack and a context that is dependent on the “program type”. They also use
statically sized key/value dictionaries called maps to store and retrieve data.
eBPF programs can make function calls into helper functions, a well-known and
stable API offered by the kernel. The next section highlights certain helper
functions that may have security side-effects and thus be of interest to attackers.
2
Mitigations automatically applied vary depending on architecture and capabilities used.
© controlplane 2024 7
eBPF Helper Functions of Interest to Threat Actors
If a threat actor can load and run eBPF code, the following helper functions3 have
particular security relevance:
1. bpf_probe_write_user
2. bpf_probe_read_user
3. bpf_override_return
4. bpf_send_signal
5. bpf_map_get_fd_by_id
Inspecting the relevant kernel headers and relevant lines in the source code
reveals the minimum Linux capabilities (KC-cap-bpf) required by the userspace
process which loads an eBPF program using each helper function:
CAP_BPF will let a process load its own eBPF programs and maps. To load some
specific program types, it must be paired with another capability. For example,
CAP_NET_ADMIN for loading network programs, and CAP_PERFMON for tracing
programs and some networking use cases. CAP_SYS_ADMIN allows any helper
function to be called.
3
For the full list of eBPF helper functions consider reading the relevant manual page
bpf-helpers(7), and consult this paper.
4
This helper is also blocked by the Kernel Lockdown feature in “integrity” mode or above.
For additional details see the recommendations in Detailed Threats and Controls.
© controlplane 2024 8
Data Flow Diagrams (DFDs)
© controlplane 2024 9
Networking
eBPF enables high-performance packet filtering and processing at various points
within the networking stack. eBPF programs attached to hooks in the kernel can
inspect, modify, or drop network packets without the need for user-space
intervention. This avoidance of mode switching reduces packet latency and
improves throughput.
XDP (eXpress Data Path) provides a framework for eBPF programs to be run as
soon as the network driver receives a packet on ingress. The kernel’s Traffic
Control (TC & TCX) layer can be used in the networking data path at both ingress
and egress and has access to the Socket Buffer structure (sk_buff). Additionally TC
hooks into generic layers and does not require driver support, which makes it
more flexible.
The TC hook is executed after the packet has been processed by the XDP hook if it
was attached to the interface.
© controlplane 2024 10
Security
eBPF security tools can combine the deep observability features of performance
monitoring and tracing tooling, while additionally making contextualised
handling decisions for anomalous events that may correspond to a threat being
realised. Policies can be defined to detect classes of events, and in some cases
prevent their ongoing execution. Prevention can be coarse (killing a suspicious
process) or fine-grained (denying an activity). For finer-grained preventions,
fmod_ret can be used to reject syscalls by altering their return values, and some
network program types also enable accept/reject semantics.
Time-of-Check Time-of-Use (TOCTOU) issues can arise in security tooling. The goal
is to analyse the actions that the system will perform accurately. However, if the
security tool reads values from user-space memory and then those values are
changed before the kernel acts on them, what is “used” by the kernel could differ
from what you “checked” in user-space. TOCTOU races can be prevented by
ensuring that the security tooling observes values after they have been
transferred to kernel memory. The two main ways to do this are LSM (Linux
Security Module) eBPF programs and directly hooking kernel internal functions
via kprobe/kretprobe/fentry/fexit
© controlplane 2024 11
Threat Model
We do not make any assumptions about the security context of tenant workloads.
Where workloads run with elevated privileges, malicious tenants could attempt to
run eBPF programs to bypass security controls.
© controlplane 2024 12
Attack trees
The following attack trees have been created as examples without any inherent
controls in place. As such, without additional exploitable vulnerabilities, some of
the theoretical attack paths will not be possible due to controls such as the
verifier.
It is important to note that the eBPF runtime itself runs in the kernel, so
vulnerabilities in controls such as the verifier may open these attack paths. Many
of these threats are equivalent to those outside of the eBPF ecosystem.
Once the key attack scenarios have been explored through the attack trees, the
threats are consolidated and summarised in Detailed Threats and Controls. The
attack trees cover platform confidentiality and integrity, availability, and evading
security tooling.
The initial compromise could come from a supply chain vulnerability, a Remote
Code Execution (RCE) attack, or an internal threat, such as an employee.
The format of the attack trees is a top-to-bottom flow. It works from the “attacker
goal” downwards, through the requirements and steps to achieve it. Leaf nodes
are grey, logical AND nodes are blue, and logical OR nodes are green.
Provided the user-space agent’s process has the correct privileges, it can attach a
Tracepoint eBPF program that observes read syscalls (or utilise kprobe/fentry) and
then use the bpf_probe_read helper function (i.e. at least with CAP_BPF and
CAP_PERFMON capabilities added) to read sensitive data.
5
Note that this also applies to any other privileged process which can load eBPF.
According to the threat model scope we are considering user-space agents with these
privileges, which we call ‘platform-level eBPF tools’.
© controlplane 2024 13
Given access to that process, an external threat actor would then require an
egress route available to the user-space agent, to exfiltrate the collected data.
If no egress route is available, an external threat actor cannot carry out this attack.
Instead, it may be undertaken by internal threat actors (e.g. privileged platform
administrators) or privileged tenants permitted to run some workloads at the
same level as the platform team.
A similar tree could be drawn if the attacker’s goal were to compromise the
integrity of data processed by a tenant workload. In this case, our eBPF program
would need to use the bpf_probe_write_user helper function. From eBPF Helper
Functions of Interest to Threat Actors, we can see that this would require the
CAP_SYS_ADMIN capability6 (whereas bpf_probe_read can be used with CAP_BPF
plus CAP_PERFMON). The use of this helper has been included as an independent
threat in Detailed Threats and Controls.
Availability
As with any code executed in the kernel, bugs or maliciously written eBPF code
may crash nodes that run tenant workloads. In Mitigating Controls, we investigate
how the eBPF verifier can mitigate these threats. At this stage of the threat model
we are simply enumerating as many types of inherent threat as possible.
Similar to the confidentiality tree, the offensive eBPF helpers which could be used
to carry out a denial of service (DoS) attack depend on the available capabilities.
For example, a security tool acting as an IPS would need to kill processes
matching indicators of compromise in a policy. To do this for legitimate purposes,
6
And additionally, a kernel prior to the addition of lockdown mode, or inactive lockdown. If
lockdown is enabled in “integrity” mode or above this helper cannot be used and this
threat is mitigated (see KC-lockdown).
© controlplane 2024 14
it would need to run with CAP_SYS_ADMIN (or as root), as CAP_PERFMON does
not permit the use of bpf_send_signal (as seen in the kernel source code). If such
a tool were to be compromised, arbitrary processes could be killed by sending a
SIGKILL, causing a denial of service to platform tenants.
If an eBPF networking tool were to be compromised (or any process with at least
the CAP_BPF and CAP_NET_ADMIN capabilities added), a denial of service attack
could be carried out by preventing traffic from reaching its intended destination.
Finally, a malicious eBPF program could disrupt a legitimate platform eBPF tool
via map tampering. The malicious program could access a map created by a
legitimate platform eBPF tool if it could use the bpf_map_get_fd_by_id libbpf
function in combination with CAP_SYS_ADMIN. By altering the data in these
maps, a denial of service attack could be carried out, for example, by tampering
with a tail call map facilitating a jump to another eBPF function.
In the first instance, if an attacker has already gained root access to a node, eBPF
could be used to build stealthy rootkit functionality. For example, the
bpf_override_return helper function can alter data returned from the kernel, so
malicious files and processes could potentially be hidden from user-space apps.
7
For the leaves of the eBPF malware branch see the Confidentiality and Integrity attack
tree above.
© controlplane 2024 15
eBPF could also be used to hide command and control (C2) traffic from clients on
the host by redirecting traffic to an attacker-controlled server using TC hooks. This
attack can be detected with traditional network detection tooling outside of the
host.
Three methods for evading eBPF security tooling are explored in the below attack
tree:
● Exploiting TOCTOU issues with tools which attach to entry points of syscalls.
This may allow an attacker to modify memory contents before the kernel
copies arguments from userspace. In this case, what is ‘checked’ by the
security tool may not be what is ‘used’.
● Executing a hook order interference attack, whereby the attacker installs
one hook converting the input from malicious to benign before the security
tool checks it and another to revert it to the malicious payload after
checking.
● Attempting to blind security tooling by creating a large amount of benign
traffic or logging. Large outputs can obscure, or even cause the loss of, data
intended for monitoring due to overflows.
© controlplane 2024 16
Mitigating Controls and
Recommendations
A full suite of mitigating controls for the threats identified in the attack trees is
included in Detailed Threats and Controls, and are summarised in this section.
After passing capability checks for loading eBPF programs, the next line of
defence when loading an eBPF program is the verifier. The verifier performs the
following checks to ensure that eBPF code is safe to run:
© controlplane 2024 17
b. Resource Access: verifies that the program accesses kernel resources
in a controlled manner, preventing resource leaks or unauthorised
access.
7. Helper Function Safety: ensures that the program only uses allowed helper
functions and that these functions are used correctly.
The verifier also checks that the process now attaching the eBPF program holds
the required capabilities for both this eBPF program type8 and the points it is
attaching to. Root privileges or the CAP_SYS_ADMIN capability are not always
necessary to run an eBPF program, and as such, it is important to understand
which capabilities are required and to apply the principle of least privilege.
For example, an eBPF networking tool may be able to be run with CAP_BPF and
CAP_NET_ADMIN, and a tracing tool may work with CAP_BPF and
CAP_PERFMON. However, a security tool (acting in prevention mode) may need to
use helper functions such as bpf_send_signal, and hence require root or
CAP_SYS_ADMIN.
Given the privileged nature of eBPF tools for networking, observability and
security, separation of duties and access control should be considered the
purview of system administrators. In a multi-tenant scenario, it is recommended
that a central platform team is responsible for the configuration and maintenance
of these tools. For this reason, disabling unprivileged eBPF is advised and
commonly the default in Linux distributions.
As with any software, regardless of the privileges it needs to run, software supply
chain security is paramount. If an attacker could compromise the source code,
build process or release artefacts of any application that runs with elevated
privileges (including platform-level eBPF tools), any threats explored in the Threat
Model could be realised. A set of supply chain security best practices can be found
in the CNCF Software Supply Chain Best Practices paper.
If closed-source eBPF software is used, some due diligence and audit activities
may not be possible (e.g. using OSSF Scorecard to see whether an open source
project complies with best practices). In this case, using a complementary open
source tool may be an option to detect or block suspicious activity.
Regardless of whether an eBPF tool is open or closed source, there will always be
the question of “who watches the watcher?”. Although some eBPF tools act as
security controls themselves, it is recommended that organisations maintain
technical threat models which consider the case that these tools themselves are
compromised. Devising controls for these threats will depend on the
organisation’s threat environment and risk appetite, but may involve using
complementary eBPF tools to detect specific classes of attack.
8
A list of eBPF program types is in the kernel documentation. Program types have been
added over time, and as such may not exist in older kernels.
© controlplane 2024 18
It is recommended that this whitepaper is used alongside the materials it
references to inform a bespoke threat model for your organisation’s systems,
accounting for the specifics of your system’s eBPF workload orchestration and
security. Once you've created a list of threats, determine the monitoring use cases
to detect these threats, and based on those use cases choose the best tool to
detect those events.
© controlplane 2024 19
Detailed Threats and Controls
This table expands upon threats from the attack trees. The “Inherent eBPF
controls” column outlines in-built protections, and “Recommendations” covers
controls to implement. Threats are unordered, and controls or recommendations
may be common to multiple threats.
1 Malicious eBPF When an eBPF program Apply the principle of least privilege.
program uses using this helper is Rather than give tools the
bpf_probe_write_ attached, a warning CAP_SYS_ADMIN capability, where
user helper including PID and possible use CAP_BPF, and additional
function to write process name is printed capabilities such as CAP_PERFMON or
to memory of to kernel logs. CAP_NET_ADMIN as required
other process (KC-cap-bpf).
3 Denial of service The verifier checks for Consider applying a cgroup to limit the
via malformed unbounded loops. Every resources available to the eBPF loading
eBPF program instruction it verifies is process, as eBPF programs inherit the
exhausting counted and the cgroup of their parent
© controlplane 2024 20
resources via program is rejected if the (KC-ebpf-cgroup).
unbounded loop number reaches a limit.
As of kernel 5.2 it’s one Resource limits - Isovalent eBPF Docs -
million instructions dylanreimerink.nl
(KC-limit-increase)
(which can be extended
with tail calls) or 4096 for
unprivileged eBPF. As
the verifier improves,
limits may be further
relaxed. You can check
for changes here or
review the current
source code.
6 Malicious eBPF If a process can obtain a Apply the principle of least privilege.
program tampers file descriptor to an eBPF Rather than give tools the
with map used object then it is assumed CAP_SYS_ADMIN capability, where
by other eBPF that future operations on possible use CAP_BPF, and additional
program, causing that object, through the capabilities such as CAP_PERFMON or
© controlplane 2024 21
a denial of descriptor, are allowed. CAP_NET_ADMIN as required.
service However, the
bpf_map_get_fd_by_id
libbpf function requires
root or CAP_SYS_ADMIN
to be used.
© controlplane 2024 22
exploitable process whereby CVE scans are
vulnerability in performed on public artefacts before
platform they are ingested. Information from
userspace vulnerability scans will include CVEs and
workload that their associated CVSS, but also can be
loads eBPF supplemented with information about
program the exploitability (e.g. KEV or EPSS
information) and software scorecards
(e.g. OSSF Scorecard).
© controlplane 2024 23
13 Enhance Linux bpf_override_return is Consider complimentary eBPF tooling
rootkits by available if the kernel to detect potentially malicious eBPF
concealing was compiled with the activity.
malicious CONFIG_BPF_KPROBE_
behaviours (post OVERRIDE configuration
exploitation), e.g. option, and operates on
modifying functions tagged with
syscalls ALLOW_ERROR_INJECTI
arguments or ON in the kernel code,
return code which is enabled by
default in many distros.
fmod_ret programs can
also perform these
actions for syscalls and
functions prefaced with
“security_”.
© controlplane 2024 24
events).
18 Lack of timely OS Programs which are Utilise eBPF programs with CO-RE and
patching leads to tightly coupled with a leveraging BTF so they’re a reduced
an exploitable kernel version can delay blocker to kernel updates. eBPF
kernel update adoption9. eBPF programs compiled for your exact
vulnerability programs can utilise kernel might not be a blocker if you or
Compile-Once your distribution provider can recompile
Run-Everywhere them.
(CO-RE). This in
combination with BPF’s Dedicate time to maintaining
stable application binary up-to-date eBPF programs for target
interface (ABI) means platforms, through ongoing testing and
you can update without integration into newer kernels as they
are released. Leverage CO-RE and BTF
changes. The one
to more easily adapt to a range of target
exception is BPF helpers
platforms.
9
Kernel CVE announcements commonly include the quote: “The Linux kernel CVE team
recommends that you update to the latest stable kernel version for this, and many other
bugfixes.”
© controlplane 2024 25
which walk kernel data
structures or call kfuncs. Failures may still occur in production,
BTF can help alleviate despite integration testing especially
issues on kernel updates when there are a lot of kernels to test.
but it is still not a stable Thus loading and functionality of BPF
ABI and no guarantees programs should be monitored in
are given and testing is production.
necessary.
Maintainers of eBPF tools leveraging
Does BPF have a Stable kfuncs should monitor kernel releases
ABI? - kernel.org/doc for BTF changes.
eBPF Tutorial by
Example: Learning
CO-RE eBPF -
eunomia.dev
(KC-bpf-link)
© controlplane 2024 26
Conclusions
eBPF is a deeply powerful foundational technology, with many benefits for the
future of infrastructure software. By safely enabling custom, kernel-level software
without requiring kernel recompilation or reboot, it provides options for increased
security over traditional approaches due to its rigorous validation of user-supplied
code.
As kernel changes or module loading are not required, eBPF is a more stable,
observable, and predictable option in environments where module-based
approaches may have been used previously. eBPF is supported by a growing
number of tools and frameworks (e.g. bpftrace, Cilium, Falco, Hubble, Tetragon)
that make it easier to implement complex use cases and effectively tackle
sophisticated networking, observability, and security challenges.
Given its generic scope, this paper is intended to inform bespoke threat models
tailored to an organisation as it plans eBPF adoption. When replacing existing
tooling with eBPF-based tools, existing policies, controls, and profiles (such as
seccomp or LSMs) should be updated accordingly as interfaces to the kernel are
different (e.g. the BPF syscall). With this approach, the many benefits of eBPF can
be realised, while risks are captured and mitigated by defence-in-depth controls.
The elevated privileges that eBPF requires do not introduce novel vulnerabilities
beyond what superuser access could achieve; rather, eBPF provides a platform for
building additional security controls that make systems more robust. While eBPF
could simplify certain attack paths for an attacker already possessing substantial
privileges, it does not make these attack vectors feasible on its own.
eBPF’s abilities enable more precise operations, making it easier to limit the risks
associated with privileged processes and improving an organisation's security
posture. By following security best practices, such as the principles of least
privilege and separation of duties, organisations can fully leverage eBPF to
enhance security and observability.
© controlplane 2024 27
Appendix
As of writing kernel 4.19 is the oldest release still under mainline maintenance.
View the current maintenance policy here. Changes prior to this release are
unlikely to be noted.
© controlplane 2024 28
References
● eBPF.io website
● eBPF Foundation website
● Shostack's 4 Question Frame for Threat Modeling - github.com
● eBPF for Anything! - isovalent.com
● Cross Container Attacks: The Bewildered eBPF on Clouds - He, Yi, et al. 2023 -
usenix.org
● Learning eBPF by Liz Rice - oreilly.com
● Introduction to CAP_BPF - mdaverde.com
● Linux 6.10 - include/uapi/linux/capability.h - git.kernel.org
● Linux 6.10 - kernel/bpf/helpers.c - git.kernel.org
● bpf-helpers(7) - Linux manual page - man7.org
● Helper functions - Isovalent eBPF Docs - dylanreimerink.nl
● bpf(2) - Linux manual page - man7.org
● Next-Generation Observability with eBPF - isovalent.com
● Linux 6.10 - struct sk_buff - docs.kernel.org
● BPF and XDP Reference Guide - Traffic Control - docs.cilium.io
● eBPF Offensive Capabilities - sysdig.com
● https://github.com/ossf/scorecard
● Linux 6.10 - eBPF Program Types - docs.kernel.org
● Program types (Linux) - Isovalent eBPF Docs - dylanreimerink.nl
● Linux 6.10 - BPF Design Q&A - kernel.org/doc
● BPF Kernel Functions (kfuncs) - kernel.org/doc
● Active Kernel Releases - kernel.org
● https://github.com/pathtofile/bad-bpf
● On Bypassing eBPF Security Monitoring - doyensec.com
● Iago Attacks: Why the System Call API is a Bad Untrusted RPC Interface -
hovav.net
● eBPF Tutorial by Example: Learning CO-RE eBPF - eunomia.dev
● An Analysis of Speculative Type Confusion Vulnerabilities in the Wild -
Kirzner, Ofek, et al. 2021 - usenix.org
● IETF RFC 9669: BPF Instruction Set Architecture (ISA) - rfc-editor.org
© controlplane 2024 29