Android Hacking, Sandboxing, & Security Exploits

Deep Dive: Understanding and Exploiting ‘neverallow’ Rules in Android SELinux Policies

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Unyielding Guard of Android SELinux

Android’s security model relies heavily on SELinux (Security-Enhanced Linux), a mandatory access control (MAC) system that enforces granular permissions beyond traditional Linux discretionary access control (DAC). At its core, SELinux prevents processes from performing actions not explicitly permitted by the policy. Among the most stringent directives in SELinux policy are neverallow rules. These rules are compile-time assertions designed to guarantee that certain critical security invariants are maintained, acting as a safeguard against accidental policy relaxations or subtle logic errors that could lead to privilege escalation. For security researchers and penetration testers, understanding and potentially circumventing neverallow rules is crucial for discovering novel attack paths.

Understanding ‘neverallow’ Rules in SELinux

A neverallow rule is a powerful declarative statement within an SELinux policy that forbids a specific interaction between a source domain, a target type, and a set of permissions. Unlike regular allow rules, which grant permissions, neverallow rules explicitly deny them, and this denial is enforced during policy compilation. If any combination of allow rules in the policy would, even indirectly, grant a permission forbidden by a neverallow rule, the policy compilation will fail.

The primary purpose of neverallow rules is multifaceted:

  • Preventing Policy Bugs: They act as a sanity check, catching errors where developers might inadvertently grant overly broad permissions.
  • Enforcing Security Critical Invariants: For example, ensuring that untrusted applications can never directly access highly sensitive system resources or perform actions that would compromise the system’s integrity.
  • Simplifying Policy Audits: By explicitly stating what *should never* happen, it makes policy review clearer and helps maintain a robust security posture over time, even as the policy evolves.

A typical neverallow rule might look like this:

neverallow untrusted_app { system_file_type } { read write execute };

This rule explicitly states that the untrusted_app domain can never have read, write, or execute permissions on any resource labeled with system_file_type. If an allow rule, or a chain of allow rules, were to implicitly grant such access, the policy compiler would flag it as an error and refuse to build the policy.

Identifying ‘neverallow’ Violations

During development, neverallow violations are often caught by tools like sepolicy-analyze or during the policy compilation process itself. When a violation occurs, the compilation typically fails with a detailed error message indicating the specific neverallow rule that was broken and the offending allow rule(s).

For example, using sepolicy-analyze with a compiled policy:

sepolicy-analyze -P /path/to/sepolicy neverallow

This command can help identify existing neverallow rules. To detect potential violations, developers usually rely on the build system’s integrated checks.

The Challenge and Art of Bypassing ‘neverallow’ Rules

Directly

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner