Summary
The KernelSU installation path writes identical hooks to both:
/data/adb/post-fs-data.d/0000liveboot
/data/adb/service.d/0000liveboot
Each hook starts an unbounded background loop that checks the app's device-protected files directory every 100 ms. If the LiveBoot APK is later removed through Android's normal package uninstaller, that directory no longer exists and neither hook can reach its exit condition. Both loops then survive for the entire uptime on every subsequent boot.
Steps to reproduce
- Install LiveBoot and select/install the KernelSU startup integration.
- Confirm the two
0000liveboot hooks exist.
- Uninstall
eu.chainfire.liveboot through Android Settings or pm uninstall, rather than invoking LiveBoot's in-app cleanup path.
- Reboot.
- Inspect the processes and the two hook files.
Actual behavior
Both hooks contain the source-generated loop:
{
while (true); do
if [ -d "/data/user_de/0/eu.chainfire.liveboot/files" ]; then
break
fi
sleep 0.1
done
/system/bin/sh /data/user_de/0/eu.chainfire.liveboot/files/liveboot
} &
With the package and data directory absent, two pollers remained alive for more than 1 day 9 hours. On the observed device they had accumulated approximately:
post-fs-data hook: 27m08s CPU, 1.3% lifetime CPU
service hook: 21m54s CPU, 1.0% lifetime CPU
Removing the two hooks and terminating the pollers immediately resolved the continuous CPU use.
Expected behavior
A stale startup hook should stop polling when the package is no longer installed. It should not remain active indefinitely after a normal APK uninstall.
Source location
The unbounded KernelSU loops are generated in Installer.java, lines 354-370.
The existing Installer.uninstall() cleanup does include the KernelSU paths, but Android's regular package removal does not execute this in-app method, so it cannot prevent the stale hooks in that removal path.
Suggested mitigation
- Use a bounded wait (and preferably exponential backoff) instead of an infinite 100 ms poll.
- If the files directory is still absent after the bounded direct-boot window, exit cleanly.
- Once PackageManager is available, verify
eu.chainfire.liveboot still exists and self-remove the stale hooks when it does not.
- Consider avoiding two independent high-frequency pollers for the same condition.
Environment
- Android 16 / SDK 36
- OnePlus PHK110 / ColorOS 16
- KernelSU userspace: ksud 3.2.5
- Package
eu.chainfire.liveboot: absent at diagnosis time
No personal log data is included.
Summary
The KernelSU installation path writes identical hooks to both:
Each hook starts an unbounded background loop that checks the app's device-protected files directory every 100 ms. If the LiveBoot APK is later removed through Android's normal package uninstaller, that directory no longer exists and neither hook can reach its exit condition. Both loops then survive for the entire uptime on every subsequent boot.
Steps to reproduce
0000liveboothooks exist.eu.chainfire.livebootthrough Android Settings orpm uninstall, rather than invoking LiveBoot's in-app cleanup path.Actual behavior
Both hooks contain the source-generated loop:
{ while (true); do if [ -d "/data/user_de/0/eu.chainfire.liveboot/files" ]; then break fi sleep 0.1 done /system/bin/sh /data/user_de/0/eu.chainfire.liveboot/files/liveboot } &With the package and data directory absent, two pollers remained alive for more than 1 day 9 hours. On the observed device they had accumulated approximately:
Removing the two hooks and terminating the pollers immediately resolved the continuous CPU use.
Expected behavior
A stale startup hook should stop polling when the package is no longer installed. It should not remain active indefinitely after a normal APK uninstall.
Source location
The unbounded KernelSU loops are generated in
Installer.java, lines 354-370.The existing
Installer.uninstall()cleanup does include the KernelSU paths, but Android's regular package removal does not execute this in-app method, so it cannot prevent the stale hooks in that removal path.Suggested mitigation
eu.chainfire.livebootstill exists and self-remove the stale hooks when it does not.Environment
eu.chainfire.liveboot: absent at diagnosis timeNo personal log data is included.