A Samsung OneUI Bug Leaked `top` Processes for Years, Crashing Banking and Government Apps Across China
The bug had been silently crashing Chinese banking, tax, railway, and carrier apps on Samsung devices for years without generating crash reports, because the kill came from AMS rather than an app-level exception. It demonstrates how a single unclosed subprocess in a vendor-customized APEX module can degrade an entire device, and why shelling out to command-line tools from a system service is a pattern worth auditing in any Android skin.
Samsung's Chinese OneUI builds contain a CPU-monitoring routine in `service-samsung-shell.jar` that calls `top -b -n 1` via `Runtime.exec`. The reader loop exits after 8 lines without ever calling `destroy()` or `close()`, leaving the `top` process orphaned as a phantom process owned by `system_server`. Each cold start or app install triggers the call when free storage drops below 3 GB, with a minimum 5-minute cooldown between invocations.
Once 32 phantom processes accumulate, Android's `trimPhantomProcessesIfNecessary` begins killing them in order of parent oom_adj. Because `system_server` runs at oom_adj -900, the cleanup logic preferentially terminates phantom processes belonging to ordinary apps. Apps protected by the enterprise version of the Bangcle packer fork a detection child process; when that child is killed, the parent app exits immediately, producing a crash that APM platforms never see because it is not a native crash.
The bug only affects mainland China firmware, where a region-gated `mIpmAntiAgingController` enables the code path. OneUI 8.5 replaces the `top` call with a proc-filesystem read, closing the leak. Users who enabled "Disable child process restrictions" merely masked the symptom while `system_server` accumulated hundreds of leaked processes and file descriptors, sometimes causing spontaneous reboots.
A single unclosed subprocess in a vendor APEX module evaded detection for years because the resulting app exits were not crashes — AMS killed the process, so APM tools never collected a stack trace.
Parsing `top` output by hardcoded column index is fragile across Android versions; the code also reads column 10 (MEM) instead of column 9 (CPU), making the CPU measurement useless even when it runs.
The phantom-process trimmer sorts by parent oom_adj, which means a leak in a high-priority system process punishes ordinary apps rather than the leaker — a design that turns a resource leak into a user-visible denial of service.
Region-gating the bug behind a China-only code path, combined with Samsung's low Chinese market share, meant the issue received almost no engineering attention despite affecting essential government and financial apps.
Praise for the author's debugging skill dominates, with one commenter admitting they had misattributed the crashes to individual apps. A separate technical reply surfaces two specific crash signatures—SIGABRT with Scudo memory corruption and SIGSEGV from getAndExecuteCommand—and notes these are predominantly reported on Samsung devices running Android 16.
Impressive. I always thought it was the app's problem, because other apps don't crash. [thumbs up]
Have you encountered either of these two issues? Currently it's mostly Samsung Android 16 reporting them. 6 (SIGABRT) Scudo ERROR: corrupted chunk header at address 0x20000791b8d8050: most likely due to memory corruption The other kind 11 (SIGSEGV) getAndExecuteCommand(fd=86) returned unexpected error -2147483648, aborting