Skip to content

Android kernel exploit for CVE-2025-38352, previously exploited in-the-wild. Targets vulnerable Linux kernels v5.10.x.

Notifications You must be signed in to change notification settings

farazsth98/chronomaly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chronomaly

Chronomaly is a kernel exploit for the Android / Linux kernel using CVE-2025-38352. The exploit was written specifically for Linux kernel v5.10.157, but should work against all vulnerable v5.10.x kernels, as it does not require any specific kernel text offsets to work.

I covered the vulnerability in detail in a three-part blog post series, all the way from PoC to exploit:

demo

Build Setup

This exploit has only been tested against an x86_64 Linux kernel v5.10.157 running in QEMU. I asked a friend to send me their Pixel 6a kernel config to base my kernel config off of, and these are the config options important for this exploit (I started from the kernelCTF config as a base):

  • CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n
  • CONFIG_PREEMPT=y (Full Preemption, no RT)
  • CONFIG_SLAB_MERGE_DEFAULT=n
  • DEBUG_LIST=n
  • BUG_ON_DATA_CORRUPTION=n
  • LIST_HARDENED=n

To disable CONFIG_POSIX_CPU_TIMERS_TASK_WORK, you can follow the steps laid out in my first blog post here.

Refer to the qemu.sh file for my QEMU run script. I used 4 cores and 3 GB RAM for testing.

Exploit parameters you'll need to change

Since the exploit depends on CPU timers, there are two parameters you may need to change to adapt it to your environment.

CPU_USAGE_THRESHOLD

This parameter is used when consuming CPU time to fire the timers inside the race_func(). It must be set such that:

  • The timers don't fire on every retry attempt (this would imply that CPU_USAGE_THRESHOLD is too high, as the timers are firing before the race_func() thread can exit).
  • The timers only fire sometimes (this would imply that sometimes the timers fire before the thread exits, and other times it fires while the thread exits).

To determine whether the timers are firing or not, insert a printf() statement in the SIGUSR1 polling code in free_func(). If you see the message print out, that means the timers fired.

If set correctly, you'll start seeing the "Parent raced too late / too early" messages in the terminal.

PARENT_SETTIME_DELAY_US

PARENT_SETTIME_DELAY_US. This parameter is used by the parent process to hit the 2nd race window inside send_sigqueue() at the same time as the child process. Run the exploit, observe, and modify it as follows:

  • The message "Parent raced too late, readjusting..." appears too often – reduce this parameter.
  • The message "Parent raced too early, readjusting..." appears too often – increase this parameter.

Ideally, you want to see both "raced too late" and "raced too early" being printed out, and the exploit will work within 1 minute. If you only see one occurring more than the other, adjust accordingly.

Potential Improvements

In my cross-cache implementation, I assumed that the kernel is not too busy, and that there haven't been many struct sigqueue allocations. I added a comment in sigqueue_crosscache_preallocs() that explains what you would need to do improve this.

If the kernel is really busy, or there are already some struct sigqueue slab pages on the per-cpu / per-node partial list, then the current cross-cache implementation in exploit.c will fail, and the uaf_sigqueue / realloc_sigqueue won't be re-allocated as a pipe buffer data page.

I purposely chose not to make the cross-cache work in a busy kernel, so that the exploit doesn't get misused :)

Questions

If you have any questions, please contact me via X / Twitter!

About

Android kernel exploit for CVE-2025-38352, previously exploited in-the-wild. Targets vulnerable Linux kernels v5.10.x.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages