AOSP Framework & Internals
3 min read

AVC Denial Analysis

Learn about AVC Denial Analysis.

When a process attempts an action prohibited by the SELinux policy, the Linux kernel blocks the action and generates an Access Vector Cache (AVC) denial message. Analyzing these messages is the primary debugging workflow for SELinux in Android.

Reading avc: denied Messages

AVC denials are printed to the kernel ring buffer and can be viewed using dmesg or logcat.

Example Denial:

type=1400 audit(16234234.123:45): avc: denied { read } for pid=456 comm="mediaserver" name="test.mp4" dev="dm-1" ino=12345 scontext=u:r:mediaserver:s0 tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0

Breaking down the message:

  • denied { read }: The requested permission was read.
  • pid=456 comm="mediaserver": The process name requesting access was mediaserver.
  • scontext=u:r:mediaserver:s0: The source context (domain) of the process.
  • tcontext=u:object_r:app_data_file:s0: The target context (type) of the object being accessed.
  • tclass=file: The class of the object.
  • permissive=0: 0 means SELinux is enforcing the denial. 1 means it is permissive (logged but allowed).

This denial translates directly into the missing allow rule: allow mediaserver app_data_file:file read;

Using audit2allow

AOSP provides a utility called audit2allow that automatically parses AVC denial messages and generates the corresponding allow rules.

To use it, capture the dmesg output and pipe it to audit2allow:

adb shell dmesg | audit2allow -p out/target/product/<device>/root/sepolicy

The output will be the formatted .te rules needed to resolve the denials.

Understanding When NOT to Use audit2allow

While audit2allow is incredibly useful, you must never blindly copy and paste its output into your policy. Doing so is a major security risk.

audit2allow only tells you what the process attempted to do; it does not tell you if the process should be allowed to do it.

Example: If an untrusted app attempts to read a system password file, audit2allow will happily generate an allow rule granting that access. Applying that rule compromises the system.

Always ask yourself: "Why does this domain need access to this specific type?"

Correct Policy Fix vs Blanket Allow

When analyzing a denial, consider the architecture. If a domain needs access to a file, perhaps the file is labeled incorrectly.

Scenario: Your new system service (my_service) is denied access to /data/misc/my_data.txt labeled as system_data_file.

Bad Fix (Blanket Allow): allow my_service system_data_file:file rw_file_perms; This grants access to all system data files, which is overly broad and likely violates a neverallow.

Correct Fix (Labeling):

  1. Define a new type: type my_service_data_file, file_type, data_file_type;
  2. Add to file_contexts: /data/misc/my_data\.txt u:object_r:my_service_data_file:s0
  3. Add specific allow rule: allow my_service my_service_data_file:file rw_file_perms;

This approach adheres to the principle of least privilege.