mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
Libc-internal file operations bypass the existing preload wrappers and still stop in PRoot. Patch recognized ARM64 SVC sites in libc and the runtime loader, reuse the current translator for 20 path syscall numbers, and return declined calls to PRoot. Enabled by default after the tracer-key check; `PROOT_FP_PATCH_SVC=0` remains the troubleshooting opt-out. The hardened implementation patches 47 sites on Thor's glibc 2.43. Relays preserve general/SIMD registers, flags, FP state and errno, and provide unwind metadata back to the original libc frame. Text is patched through `/proc/self/mem` after relay pages become executable. Initialization skips multiple live threads and SVE/SME. Alternate signal stacks and insufficient remaining stack use PRoot; main-stack growth respects the current limit. No proroot code or binaries are imported. Robust-list set/get sites deliberately remain with PRoot/the kernel. Device tests reproduced stale state when the earlier private-TLS implementation mixed patched and raw callers. Removing that shortcut fixes coherence and preserves the host's actual return policy; the earlier thread-creation gain is retired. SDK forwarding still enables faccessat2 ENOSYS fallback and clone3 ENOSYS only before Android 15. Successful clone3 is never executed from the C relay. Existing fsync handling is unchanged. No in-process RET_TRAP filter is added, so SIGSYS-mask/handler machinery is not applicable. Version-2 build-ID/API tables cache relative patch sites in `/tmp`. Every hit revalidates executable bounds, alignment, instructions and syscall numbers. Invalid/unsafe files rescan; publication uses a private temporary file and atomic rename. The PRoot dependency fetch also gains a mirror matching the existing pinned checksum, resolving upstream availability failures without changing versions. Five alternating pairs using the final bundled library on Thor/Android 13: | operation | wrappers only | hardened relays | |---|---:|---:| | libc-internal stat | 49.6 us | 6.0 us | | libc-internal open/close | 50.4 us | 7.8 us | | libc faccessat | 49.7 us | 22.0 us | | libc getcwd | 54.9 us | 5.0 us | | thread create/join | 136 us | 144 us | | complete tiny exec/wait | 4.44 ms | 5.60 ms | An earlier five-pair hardened-library run measured stat 50.1 to 5.9 us and open/close 51.9 to 7.1 us. The metadata gains survive the safety checks. Neither run shows a thread-creation gain, and tiny execs retain roughly 0.9-1.2 ms overhead. Three full Steam startup pairs yielded Home-ready medians of 47.02 s off / 45.25 s on, with overlapping 43-50 s ranges. Steam/CEF-only PSS medians were 1,223.1 / 1,233.9 MiB; the roughly 11 MiB difference is smaller than observed variation, but does not establish zero memory cost. Startup/memory used one unchanged signed bundled-library APK without overrides; the final stack-gap guard only increases distance reserved above other mappings. No reliable whole-client startup improvement is claimed. Earlier fresh Half-Life SD installs took 350/341 s off and 326/327 s on. These are historical results from the preceding robust-list revision, not a post-hardening download retest. Network/shader scheduling varied, allocation did not reliably improve, and the repeat baseline committed faster. This PR demonstrates metadata acceleration; it does not demonstrate a reliable fix for Steam's SD allocation/commit bottleneck. Validation on `2c3c135b` (production code unchanged since `4998b046`): - Local release build, runtime/native-library checks, release signing and four focused Android tests pass. [Final-head CI](https://github.com/Droid-Deck/DroidDeck/actions/runs/40704837477) passed: 1,431 Python/native tests (49 skips), 2,648 Android tests (zero failures/skips), and 162 Rust tests. CodeRabbit is green on the same head. The installed production APK forwards API 33 and patches 47 sites with an unset enable flag and no override; Steam Home renders. - Embedded and shared-PIC matrices pass on glibc 2.43; shared-PIC also passes on separately loaded glibc 2.39. Coverage includes raw results/errno/registers/FP state, path/flag/error and protected-pointer cases, exact readlink boundaries, mixed raw/relay robust state, concurrent threads, fork, thread churn, alternate-stack signals, deferred/FIFO cancellation, signal siglongjmp recovery, forced unwind with caller cleanup, and limited remaining stack. - Four device test-process filters deny the memory patch file, relay mapping, executable permission, or patch writes. Every case leaves original syscall execution working. Host injection also verifies partial installation after an individual site fails. - Concurrent atomic symlink replacement passes 3,000 internal stat/readlink iterations at default/zero TTL. Eight focused host tests pass, covering instruction/branch limits, stack/limit fallback, untrusted cache files and NDEBUG checks. API selection gives 45/47/46 sites for unknown/33/simulated-35; unset and explicit 1 agree, and 0 leaves sites untouched. This does not replace Android 15 hardware testing. - All bench tools compile with -DNDEBUG. Relative/absolute fixture workloads agree, and thread/ABI/failure checks pass on Thor with those builds. - Earlier internal fts/realpath/NSS/dlopen and normalized read-path equivalence pass. The write suite retains the existing wrapper SD Unix-socket mismatch against PRoot. CodeRabbit disposition: fixed relative fixture paths, prevented benchmark checks disappearing under NDEBUG, corrected the limited-fallback description, and narrowed memory-file denial so the thread check still succeeds. The default-off recommendation was addressed by fixing/testing the underlying guard and unwind issue while retaining the requested default-on behavior. The readlink count suggestion is intentionally not adopted: device boundary comparisons reproduce current PRoot behavior, so changing that inherited policy belongs in a separate correctness change. This is not consequence-free instruction patching: constructor time, private text copies and stack checks have costs. Android 15+ ARM64 and 16 KiB-page hardware, arbitrary asynchronous cancellation/non-local exits, user-managed stacks, and attributable tracer-counter measurements remain gaps. Loader calls before the constructor and arbitrary guest ELF syscall sites remain outside scope. Thor was restored to its original APK and bundled library, with app data preserved and test settings, overrides, temporary files and version-2 test caches cleared. Detailed evidence and revision boundaries: [proroot analysis](https://github.com/Droid-Deck/DroidDeck/blob/2c3c135b52c3dd949ef5a99a67d8c12eba24406c/docs/development/proroot-analysis.md).