Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@
- [Objection Tutorial](mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md)
- [Google CTF 2018 - Shall We Play a Game?](mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md)
- [In Memory Jni Shellcode Execution](mobile-pentesting/android-app-pentesting/in-memory-jni-shellcode-execution.md)
- [Inputmethodservice Ime Abuse](mobile-pentesting/android-app-pentesting/inputmethodservice-ime-abuse.md)
- [Insecure In App Update Rce](mobile-pentesting/android-app-pentesting/insecure-in-app-update-rce.md)
- [Install Burp Certificate](mobile-pentesting/android-app-pentesting/install-burp-certificate.md)
- [Intent Injection](mobile-pentesting/android-app-pentesting/intent-injection.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,46 @@ void *deleter(void *arg) {

- Race amplifiers: high scheduler tick rate, CPU load, repeated thread exit/re-create cycles. The crash typically manifests when posix_cpu_timer_del() skips noticing firing due to failing task lookup/locking right after unlock_task_sighand().

Detection and hardening
- Mitigation: apply the exit_state guard; prefer enabling CONFIG_POSIX_CPU_TIMERS_TASK_WORK when feasible.
- Observability: add tracepoints/WARN_ONCE around unlock_task_sighand()/posix_cpu_timer_del(); alert when it.cpu.firing==1 is observed together with failed cpu_timer_task_rcu()/lock_task_sighand(); watch for timerqueue inconsistencies around task exit.
### Userspace race trigger (poc-CVE-2025-38352)

[Faith's PoC write-up](https://faith2dxy.xyz/2025-12-22/cve_2025_38352_analysis/) and the accompanying [poc-CVE-2025-38352](https://github.com/farazsth98/poc-CVE-2025-38352) repository show a completely userland-controlled way to force the race:

- Build/boot a vulnerable LTS 6.12.33 kernel where `CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n`, then run the statically linked PoC inside the guest.
- The child process spawns a `SLOWME` thread pinned to CPU2, arms a `CLOCK_THREAD_CPUTIME_ID` timer that uses `SIGEV_THREAD`, and sets the initial expiration (`wait_time`, default 250000 ns) so that the timer fires immediately after `exit_notify()` transitions the thread into `EXIT_ZOMBIE`.
- Pipes and a `pthread_barrier` keep the timer thread paused until the parent attaches with `ptrace(ATTACH)` on CPU1, continues it, and later reaps it with `waitpid(tid, __WALL)` so that `release_task()` nulls `tsk->sighand` while `handle_posix_cpu_timers()` is still iterating its private `firing` list.
- Once the parent signals that the thread has been reaped, the child calls `timer_delete()` (while the timer is still referenced by the IRQ handler) and immediately issues a global `membarrier()` to wait for the RCU free, guaranteeing deterministic UAFs or WARN splats.
- CPU affinity and a busy loop in the timer thread make the CPU timer accrue runtime fast enough that the race can be hit in a tight shell loop (`while true; do ./poc; done`).

Key synchronization in the PoC looks like:

```c
SYSCHK(ptrace(PTRACE_ATTACH, tid, NULL, NULL));
SYSCHK(waitpid(tid, NULL, __WALL));
SYSCHK(ptrace(PTRACE_CONT, tid, NULL, NULL));
SYSCHK(read(p2c[0], &m, 1)); // parent tells child the thread was reaped
timer_delete(timer); // frees timer while handler still runs
wait_for_rcu(); // membarrier to let k_itimer retire
```

### Extending race windows for lab reliability

The repository ships an `mdelay_patch.diff` that hard-codes a half-second busy wait inside `handle_posix_cpu_timers()` whenever `tsk->comm == "SLOWME"`:

```c
unlock_task_sighand(tsk, &flags);
if (strcmp(tsk->comm, "SLOWME") == 0) {
printk("Faith: Did we win? tsk->exit_state: %d\n", tsk->exit_state);
mdelay(500);
}
```

While unnecessary for real exploitation, inflating the critical section makes it trivial to overlap `timer_delete()` with the IRQ handler and is a reusable trick for validating other tight kernel races: temporarily add an `mdelay()`/`udelay()` gate that only fires for test threads identified by `comm` or `pid`, then remove it once the exploit strategy is proven.

### Configuration and lab setup notes

- `CONFIG_POSIX_CPU_TIMERS_TASK_WORK` is hidden behind `HAVE_POSIX_CPU_TIMERS_TASK_WORK`, so the PoC exposes it by editing `kernel/time/Kconfig` and turning the entry into `bool "CVE-2025-38352: POSIX_CPU_TIMERS_TASK_WORK toggle" if EXPERT` with `default y`. After that, `make menuconfig` can flip the option to `n` on x86/arm64 for research builds.
- Run the vulnerable kernel in a multi-core VM (the author used `qemu-system-x86_64 -enable-kvm -cpu host -smp cores=4 ...`) because at least two physical CPUs are required: one for the timer thread burning CPU time, another for the parent reaper, and a third to service the IRQ handler deterministically.
- The PoC builds with the provided `Makefile` (`gcc -o poc -static poc.c`). Pass different `wait_time` values (`./poc 200000`, `./poc 300000`, etc.) to align the timer expiration with `exit_notify()`, then loop execution until the kernel splats.
Audit hotspots (for reviewers)
- update_process_times() → run_posix_cpu_timers() (IRQ)
- __run_posix_cpu_timers() selection (TASK_WORK vs IRQ path)
Expand All @@ -207,6 +243,8 @@ Notes for exploitation research

## References
- [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/)
- [CVE-2025-38352 - In-the-wild Android Kernel Vulnerability Analysis + PoC](https://faith2dxy.xyz/2025-12-22/cve_2025_38352_analysis/)
- [PoC repository: poc-CVE-2025-38352](https://github.com/farazsth98/poc-CVE-2025-38352)
- [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01)
- [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,4 @@ adb shell ime help
- **User/MDM**: allowlist trusted keyboards; block unknown IMEs in managed profiles/devices.
- **App-side (high risk apps)**: prefer phishing-resistant auth (passkeys/biometrics) and avoid relying on “secret text entry” as a security boundary (a malicious IME sits below the app UI).

{{#include ../../banners/hacktricks-training.md}}