fix(magisk): denylist (package, process) remodel so root hides in the DroidGuard process - #270
Merged
Merged
Conversation
… DroidGuard process (#170) Magisk keys its denylist on (package_name, process), but magisk-config.sh copied each entry into BOTH columns and the default listed com.google.android.gms.unstable — the DroidGuard/Play-Integrity *process* of com.google.android.gms — as if it were a package. A row with package_name='com.google.android.gms.unstable' matches no installed app, so vanilla (non-Shamiko) Magisk never hid root in the attestation process. Minimal-churn fix (keeps the BEETROOT_DENYLIST_PACKAGES env-var contract, so the compose template is untouched): - denylist entries now take a `package[/process]` shape (no slash => process is the package); default = (com.google.android.gms, com.google.android.gms/com.google.android.gms.unstable) - the grammar validates BOTH halves (SQL-injection prophylaxis intact) - magisk-config.sh splits on the first '/' and inserts the real package into package_name and the process into process, never both - the redroid/adb denylist health check matches enrolment by the package half - docs + all example configs demonstrate the corrected form All covered by tests (incl. a guard that .unstable never appears in package_name); full gate green (ruff, mypy --strict src+tests, pytest 100% line+branch (1987 passed), shellcheck/shfmt, yamllint, codespell, deptry, uv lock, changelog lint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P1YsNMpGizhSDDPCBu5cut
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #170 — the last substantive item from the original 71-issue triage, and the one deferred from PR #249 for its blast radius.
Magisk keys its denylist on
(package_name, process), butmagisk-config.shcopied each entry into both columns, and the default listedcom.google.android.gms.unstable— the DroidGuard / Play-Integrity process ofcom.google.android.gms— as if it were a package. A row withpackage_name='com.google.android.gms.unstable'matches no installed app, so vanilla (non-Shamiko) Magisk never hid root in the attestation process — defeating the denylist's main purpose.The fix (minimal-churn)
Kept the
BEETROOT_DENYLIST_PACKAGESenv-var contract stable (so the compose template and its tests are untouched):package[/process]shape (no slash ⇒ the process is the package). Default:(com.google.android.gms, com.google.android.gms/com.google.android.gms.unstable).magisk-config.shsplits on the first/and inserts the real package intopackage_nameand the process intoprocess— never copying one value into both.pkg/process-only config still counts as enrolled).default,lsposed,with-frida,stealth) demonstrate the corrected form (.unstable/.persistentare GMS processes, not packages).Testing
New tests include a guard that
.unstablenever appears inpackage_name, no-slash/slash split cases, a process-only-entry-still-enrols case, and the corrected default. Full local gate green:ruff,mypy --strict(src+tests),pytest -p no:randomlyat 100% line+branch coverage (1987 passed, 6 docker-daemon skips),shellcheck/shfmt,yamllint,codespell,deptry,uv lock --check, changelog lint.🤖 Generated with Claude Code
https://claude.ai/code/session_01P1YsNMpGizhSDDPCBu5cut
Generated by Claude Code