[SECURITY] BPF task_work context confusion enables cross-process bpf_probe_write_user() via token delegation
From: Keshav goyal
Date: Sun May 03 2026 - 10:29:34 EST
Hello Linux Kernel Security Team,
I would like to report a potential security issue in the BPF subsystem involving task_work scheduling and context confusion.
Summary
-------
A BPF tracing program can target an arbitrary PID using bpf_task_from_pid() and schedule a callback via bpf_task_work_schedule_signal(). The callback executes in the context of the target task, allowing bpf_probe_write_user() to write into that task’s userspace memory.
This effectively turns the helper from “write current task memory” into “write arbitrary target process memory”.
Impact
------
This creates a cross-process userspace memory write primitive.
I have confirmed that:
- The target process can be root-owned
- No ptrace or same-UID checks are required
- The write occurs successfully in the victim process memory
Importantly, I was able to reproduce this not only as root, but also via a token-delegated BPF loader in a user namespace (using libbpf BPF token support).
This suggests a potential privilege-boundary bypass depending on deployment of delegated BPF capabilities.
Proof of Concept
----------------
I am attaching:
- PoC source code
- build + run instructions
- screenshots demonstrating memory modification
- logs showing successful execution
Key observed output:
scheduled=... ran=... err=0
BUF=AAAAAAAAAAAAAAAA
BUF=BPFOKAAAAAAAAAAA
This confirms that a BPF program modified memory of another process.
Root Cause
----------
The issue appears to arise from the following behavior:
- bpf_task_from_pid() resolves arbitrary tasks
- bpf_task_work_schedule_signal() queues attacker-controlled work
- task_work executes in the target task context (current == victim)
- bpf_probe_write_user() writes to current->mm without validating origin
This combination allows cross-process memory writes.
Environment
-----------
- Kernel: upstream built from kernel.org (latest mainline at time of testing)
- Architecture: x86_64
- Test setup: QEMU VM with custom kernel
- BPF features: BTF enabled, tracing programs allowed, lockdown disabled
Reproduction
------------
I have included step-by-step reproduction instructions in the attached materials. The issue is reliably reproducible.
I was able to reproduce the same behavior using a token-delegated BPF loader running inside a user namespace (via LIBBPF_BPF_TOKEN_PATH), rather than directly as init-namespace root.
In this setup:
- The loader runs as a non-root user (UID 1000 mapped inside a user namespace)
- BPF access is granted via a token
- The target process is still a root-owned process in the init namespace
Even in this configuration, the BPF program successfully schedules task_work on the target and bpf_probe_write_user() modifies the victim’s userspace memory.
Example output:
scheduled=... ran=... err=0
BUF=AAAAAAAAAAAAAAAA
BUF=BPFOKAAAAAAAAAAA
This suggests the behavior is not limited to fully privileged root contexts, but also applies in delegated BPF scenarios.
Request
-------
I would appreciate your guidance on:
- whether this is considered a valid security boundary violation
- recommended disclosure process
- whether additional hardening or checks are expected here
Please let me know if any additional information or testing is required.
Thank you for your time and for maintaining the kernel.
Best regards,
Keshav Goyal






I would like to report a potential security issue in the BPF subsystem involving task_work scheduling and context confusion.
Summary
-------
A BPF tracing program can target an arbitrary PID using bpf_task_from_pid() and schedule a callback via bpf_task_work_schedule_signal(). The callback executes in the context of the target task, allowing bpf_probe_write_user() to write into that task’s userspace memory.
This effectively turns the helper from “write current task memory” into “write arbitrary target process memory”.
Impact
------
This creates a cross-process userspace memory write primitive.
I have confirmed that:
- The target process can be root-owned
- No ptrace or same-UID checks are required
- The write occurs successfully in the victim process memory
Importantly, I was able to reproduce this not only as root, but also via a token-delegated BPF loader in a user namespace (using libbpf BPF token support).
This suggests a potential privilege-boundary bypass depending on deployment of delegated BPF capabilities.
Proof of Concept
----------------
I am attaching:
- PoC source code
- build + run instructions
- screenshots demonstrating memory modification
- logs showing successful execution
Key observed output:
scheduled=... ran=... err=0
BUF=AAAAAAAAAAAAAAAA
BUF=BPFOKAAAAAAAAAAA
This confirms that a BPF program modified memory of another process.
Root Cause
----------
The issue appears to arise from the following behavior:
- bpf_task_from_pid() resolves arbitrary tasks
- bpf_task_work_schedule_signal() queues attacker-controlled work
- task_work executes in the target task context (current == victim)
- bpf_probe_write_user() writes to current->mm without validating origin
This combination allows cross-process memory writes.
Environment
-----------
- Kernel: upstream built from kernel.org (latest mainline at time of testing)
- Architecture: x86_64
- Test setup: QEMU VM with custom kernel
- BPF features: BTF enabled, tracing programs allowed, lockdown disabled
Reproduction
------------
I have included step-by-step reproduction instructions in the attached materials. The issue is reliably reproducible.
I was able to reproduce the same behavior using a token-delegated BPF loader running inside a user namespace (via LIBBPF_BPF_TOKEN_PATH), rather than directly as init-namespace root.
In this setup:
- The loader runs as a non-root user (UID 1000 mapped inside a user namespace)
- BPF access is granted via a token
- The target process is still a root-owned process in the init namespace
Even in this configuration, the BPF program successfully schedules task_work on the target and bpf_probe_write_user() modifies the victim’s userspace memory.
Example output:
scheduled=... ran=... err=0
BUF=AAAAAAAAAAAAAAAA
BUF=BPFOKAAAAAAAAAAA
This suggests the behavior is not limited to fully privileged root contexts, but also applies in delegated BPF scenarios.
Request
-------
I would appreciate your guidance on:
- whether this is considered a valid security boundary violation
- recommended disclosure process
- whether additional hardening or checks are expected here
Please let me know if any additional information or testing is required.
Thank you for your time and for maintaining the kernel.
Best regards,
Keshav Goyal
IMG1:

IMG2:

IMG3:

IMG4:

IMG5.1:

IMG5.2:

Attachment:
BPF POC.md
Description: Binary data