How Magisk Handles SELinux Policies with magiskpolicy
Magisk handles SELinux policies through the standalone magiskpolicy Rust binary, which patches the kernel's security policy at boot by loading the stock configuration, injecting built-in Magisk rules, and merging module-specific statements before writing the result directly to /sys/fs/selinux/policy.
The topjohnwu/Magisk repository implements a comprehensive SELinux management system centered on the magiskpolicy utility. This tool allows the framework to modify mandatory access controls without recompiling entire policy binaries, enabling root functionality while maintaining Android's security model.
What Is magiskpolicy and Where It Lives
The magiskpolicy binary is a Rust-based utility that serves as the primary interface for SELinux policy manipulation in Magisk.
Source Code Location
The implementation resides in the native Rust codebase:
native/src/sepolicy/cli.rs– Contains the command-line interface implementation, argument parsing, and policy statement handling logic.native/src/sepolicy/Cargo.toml– Defines the crate configuration and links againstlibsepolfor low-level policy operations.
Build System Integration
The binary is compiled through the Android NDK build system as defined in native/src/Android.mk, which packages magiskpolicy alongside other Magisk native components. During the build process, the Rust crate is compiled into a static binary suitable for Android's execution environment.
Legacy Compatibility
For backward compatibility with legacy SuperSU scripts, scripts/live_setup.sh creates a symbolic link exposing magiskpolicy as supolicy:
ln -s ./magiskpolicy $MAGISKTMP/supolicy
This alias ensures existing modules and scripts referencing the older supolicy command continue to function correctly.
Loading and Applying Policies at Boot
During the live-boot stage, Magisk orchestrates policy patching through scripts/live_setup.sh to establish the necessary security context for daemon operation.
The Boot-Time Orchestration
The setup script invokes magiskpolicy with specific flags to load the device's stock policy and inject Magisk-specific rules:
./magiskpolicy --load /vendor/etc/selinux/precompiled_sepolicy --live --magisk $RULESCMD
./magiskpolicy --load /sepolicy --live --magisk $RULESCMD
./magiskpolicy --live --magisk $RULESCMD
These commands attempt to load the precompiled vendor policy first, falling back to the root /sepolicy file if unavailable, and finally operating on the current live policy if neither file exists.
Command-Line Flags Explained
Each flag serves a distinct function in the policy pipeline:
--load <file>– Reads a monolithic policy binary from the specified path (e.g.,/vendor/etc/selinux/precompiled_sepolicy).--live– Sends the modified policy directly to the kernel via the/sys/fs/selinux/policyinterface, applying changes immediately without reboot.--magisk– Automatically injects the built-in Magisk rule set, effectively executingallow magisk * * *to permit the Magisk domain universal access.
The $RULESCMD variable contains additional policy statements supplied by the user or modules, passed internally using the --apply mechanism.
Policy Syntax and Capabilities
The magiskpolicy parser, implemented in native/src/sepolicy/cli.rs, supports a statement format mirroring classic SELinux .te (Type Enforcement) syntax supplied via command-line arguments.
Supported Statement Types
According to the documentation in docs/tools.md, the utility recognizes several policy statement types:
allow *source_type *target_type *class *perm_set– Standard access control rules allowing a source domain to perform actions on target objects.allowxperm …– Extended permission rules (X-perm) for ioctl controls, introduced for Android O compatibility.permissive ^type– Switches a specific domain to permissive mode for debugging.enforce ^type– Re-enables enforcing mode for a specified domain.
Arguments may be specified as wildcards (*), lists (e.g., { s1 s2 }), or specific identifiers, providing flexibility in rule definition.
Extending Policies via Magisk Modules
Magisk modules can ship custom SELinux rules without modifying the core policy binary, leveraging the --apply interface for safe, isolated extensions.
Module Policy Files
Modules typically include a sepolicy.rules file within their directory structure (/data/adb/modules/<module>/sepolicy.rules). When Magisk initializes modules during boot, it invokes:
./magiskpolicy --live --magisk --apply /data/adb/modules/<module>/sepolicy.rules
Runtime Merging Process
The merging logic concatenates parsed statements from the module's rule file into the in-memory policy representation before committing the final policy to the kernel. This approach allows modules to declare necessary permissions (e.g., accessing hardware nodes or system properties) without conflicting with the stock SELinux configuration or other modules.
Runtime Usage and Developer Workflows
Beyond boot-time automation, magiskpolicy functions as a standalone developer tool for debugging and policy analysis.
Direct Shell Invocation
Developers can invoke the binary directly from an ADB shell or terminal emulator to inspect or modify the current security policy:
# Display all active rules in the running policy
magiskpolicy --print-rules
# Inject a temporary rule for testing
magiskpolicy --live "allow my_app file file { read write }"
Advanced Policy Operations
The CLI supports additional workflows for policy manipulation:
--save <file>– Exports the current live policy to a binary file for offline analysis.--load-split– Handles split policy configurations common in newer Android versions, loading from/vendor/etc/selinux/precompiled_sepolicyand associated split contexts.
These capabilities enable developers to extract stock policies, modify them using external tools, and re-inject the modified versions for testing.
Summary
magiskpolicyis a Rust binary located innative/src/sepolicy/that serves as Magisk's sole interface for SELinux manipulation.- At boot,
scripts/live_setup.shinvokes the tool with--load,--live, and--magiskflags to patch the kernel policy and establish themagiskdomain. - Modules extend policies by placing rules in
sepolicy.rulesfiles, processed via the--applyflag during module loading. - The tool supports standard SELinux syntax including
allow,allowxperm, andpermissivestatements with wildcard and list expansion. - Runtime usage via
--print-rulesand--saveenables debugging and policy analysis without requiring a full rebuild cycle.
Frequently Asked Questions
What is the difference between magiskpolicy and supolicy?
magiskpolicy is the current binary name for Magisk's SELinux policy tool, while supolicy is a legacy alias maintained for backward compatibility. During initialization, scripts/live_setup.sh creates a symbolic link from magiskpolicy to supolicy, ensuring older modules and scripts referencing the SuperSU-era command continue to function without modification.
How do I add custom SELinux rules to a Magisk module?
Create a file named sepolicy.rules in your module's root directory (/data/adb/modules/<your-module>/). Place valid SELinux statements inside using standard Type Enforcement syntax (e.g., allow my_daemon property_type property_service { set }). Magisk automatically passes this file to magiskpolicy --apply during the boot sequence, merging your rules into the live kernel policy.
Can I use magiskpolicy to modify policies on a running device?
Yes. The --live flag enables runtime policy modification without rebooting. You can execute commands like magiskpolicy --live "allow my_app device chr_file { read write }" from a root shell to temporarily extend permissions. However, these changes persist only until the next reboot unless incorporated into a module's sepolicy.rules file.
Where does magiskpolicy store the modified policy?
The tool does not store policies in persistent storage by default. When using --live, it writes directly to /sys/fs/selinux/policy, modifying the kernel's in-memory policy representation. To save a policy binary for offline editing, use the --save <filename> flag, which exports the current live policy to the specified file path.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →