diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 91c0f338a63..83272cb8044 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -439,6 +439,7 @@
- [Android Enterprise Work Profile Bypass](mobile-pentesting/android-app-pentesting/android-enterprise-work-profile-bypass.md)
- [Android Hce Nfc Emv Relay Attacks](mobile-pentesting/android-app-pentesting/android-hce-nfc-emv-relay-attacks.md)
- [Android Physical Attacks](mobile-pentesting/android-app-pentesting/android-physical-attacks.md)
+ - [Android SELinux Domains, AVC Denials and Policy Manipulation](mobile-pentesting/android-app-pentesting/android-selinux-domains-and-policy-manipulation.md)
- [Android Task Hijacking](mobile-pentesting/android-app-pentesting/android-task-hijacking.md)
- [Android VPN Bypass](mobile-pentesting/android-app-pentesting/android-vpn-bypass.md)
- [ADB Commands](mobile-pentesting/android-app-pentesting/adb-commands.md)
diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md
index 4336bcabbff..2049f26ec8e 100644
--- a/src/mobile-pentesting/android-app-pentesting/README.md
+++ b/src/mobile-pentesting/android-app-pentesting/README.md
@@ -36,6 +36,10 @@ Sometimes it is useful to **modify application code** to access **hidden informa
- [Android app-level virtualization / app cloning abuse & detection](android-application-level-virtualization.md)
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md)
+{{#ref}}
+android-selinux-domains-and-policy-manipulation.md
+{{#endref}}
+
{{#ref}}
../../binary-exploitation/linux-kernel-exploitation/futex-pi-uaf-pipe-buffer-workqueue-usermodehelper.md
{{#endref}}
diff --git a/src/mobile-pentesting/android-app-pentesting/android-selinux-domains-and-policy-manipulation.md b/src/mobile-pentesting/android-app-pentesting/android-selinux-domains-and-policy-manipulation.md
new file mode 100644
index 00000000000..f675a2cce42
--- /dev/null
+++ b/src/mobile-pentesting/android-app-pentesting/android-selinux-domains-and-policy-manipulation.md
@@ -0,0 +1,190 @@
+# Android SELinux Domains, AVC Denials and Policy Manipulation
+
+{{#include ../../banners/hacktricks-training.md}}
+
+Android SELinux is a second authorization boundary after the Linux UID sandbox. The techniques below are for rooted, `userdebug`/`eng`, or otherwise policy-modifiable research devices: they remove MAC restrictions **after** privileged access exists and are not an initial-access exploit.[[9]](#references)
+
+## From APK identity to process domain
+
+Android derives an application's process domain and data-file type from two policy inputs. `mac_permissions.xml` maps a signing identity (optionally refined by package name) to `seinfo`; `seapp_contexts` then matches `seinfo` together with selectors such as UID class, package name, privileged/ephemeral status, target SDK, and isolated/SDK-sandbox state. Its `domain` output labels the process, `type` labels the app data directory, and `levelFrom` derives MLS/MCS categories used for per-app separation.[[1]](#references)[[2]](#references)[[9]](#references)
+
+```text
+APK certificate/package
+ -> mac_permissions.xml -> seinfo
+ -> seapp_contexts selectors
+ -> domain (process)
+ -> type + levelFrom (data directory and categories)
+```
+
+At installation, PackageManager delegates data-directory labeling to `installd`, which applies the selected object type. At launch, Zygote forks and calls `selinux_android_setcontext()` before application code executes, so the child enters its selected domain while the parent remains `zygote`.[[9]](#references)
+
+Inspect the effective mapping and runtime labels on the device as follows.[[1]](#references)[[9]](#references)
+
+```bash
+adb shell cat /system/etc/selinux/plat_mac_permissions.xml
+adb shell cat /system/etc/selinux/plat_seapp_contexts
+adb shell ps -AZ | grep com.example.target
+adb shell run-as com.example.target cat /proc/self/attr/current
+adb shell ls -Zd /data/user/0/com.example.target # root usually required
+```
+
+Do not assume that raw line order alone determines the winner on current AOSP. Entries are sorted by a defined specificity precedence and apps are checked until the first match; fixed/longer `user` or `name` selectors outrank prefixes, specified `seinfo` outranks unspecified `seinfo`, and platform entries outrank vendor entries at the final precedence step.[[1]](#references)
+
+A package-specific mapping can therefore force a research APK into another existing domain on a policy-modifiable image. This changes the SELinux domain and data type, **not** its Linux UID, and the target domain must already exist with suitable policy rules.[[1]](#references)[[9]](#references)
+
+```text
+user=_app seinfo=default name=com.example.research \
+ domain=system_app type=system_app_data_file levelFrom=user
+```
+
+On production images, AVB/dm-verity and partitioned policy normally prevent directly replacing `/system/etc/selinux/plat_seapp_contexts`; use an explicitly modifiable lab image or a root framework's supported boot-time mechanism instead of assuming a remount is sufficient.[[9]](#references)
+
+## Turn AVC denials into policy tuples
+
+An AVC record directly describes the rejected tuple: permissions in `{ ... }`, source domain in `scontext`, target type/domain in `tcontext`, and object class in `tclass`. For example, the record below means the `shell` domain lacks `proc_mem:file { open read write }`; `permissive=0` means enforcement blocked the request.[[3]](#references)[[9]](#references)
+
+```text
+avc: denied { open read write } for pid=8821 comm="exploit_poc" name="mem"
+ scontext=u:r:shell:s0
+ tcontext=u:object_r:proc_mem:s0
+ tclass=file permissive=0
+```
+
+Collect a clean window while reproducing the operation. Availability of kernel logs differs between production and debug builds.[[3]](#references)[[9]](#references)
+
+```bash
+adb shell su -c 'dmesg -w | grep "avc:"'
+adb logcat -b all | grep 'avc:'
+adb shell su -c 'cat /proc/kmsg' | grep 'avc:'
+```
+
+If an access fails without a visible AVC, check whether `dontaudit` suppresses it. Android builds of SETools can query the live binary policy; compare these rules with the failing source, target and class, and use a temporary per-domain permissive test only on an isolated lab device to collect the rest of the denial chain.[[8]](#references)[[9]](#references)
+
+```bash
+adb push sesearch /data/local/tmp/ && adb shell chmod 755 /data/local/tmp/sesearch
+adb shell /data/local/tmp/sesearch --dontaudit /sys/fs/selinux/policy \
+ | grep -E '(^dontaudit shell |^dontaudit untrusted_app )'
+adb shell su -c "magiskpolicy --live 'permissive shell'"
+# Reproduce, collect AVCs, then restore enforcement:
+adb shell su -c "magiskpolicy --live 'enforce shell'"
+```
+
+`audit2allow` is useful for translating captured denials, but its output is only a starting point: blindly applying it can grant sensitive kernel-memory or device access. Reduce every candidate to the exact source, target, class and permissions required by the PoC.[[3]](#references)
+
+```bash
+adb pull /sys/fs/selinux/policy ./policy
+adb logcat -b events -d | audit2allow -p ./policy
+```
+
+## File types, `chcon` and `restorecon`
+
+A PoC may have the correct UID and process domain but still fail because its executable or library has the wrong target type. Files copied to `/data/local/tmp` normally acquire a path-defined label such as `shell_data_file`; with root, `chcon` can temporarily select a type for which the caller has `execute`, `entrypoint`, `map`, or read permissions.[[4]](#references)[[9]](#references)
+
+```bash
+adb push exploit_poc /data/local/tmp/
+adb shell su -c 'ls -Z /data/local/tmp/exploit_poc'
+adb shell su -c 'chcon u:object_r:shell_exec:s0 /data/local/tmp/exploit_poc'
+adb shell su -c 'ls -Z /data/local/tmp/exploit_poc'
+```
+
+This does not persist against `restorecon`, filesystem relabeling, or boot-time relabel logic. `restorecon` resolves the expected type from merged, regex-based `file_contexts` files, so always record the original label and restore it after testing.[[4]](#references)[[9]](#references)
+
+```bash
+adb shell su -c 'restorecon -v /data/local/tmp/exploit_poc'
+adb shell su -c 'cat /system/etc/selinux/plat_file_contexts' | grep '/data/local/tmp'
+adb shell su -c 'cat /vendor/etc/selinux/vendor_file_contexts' | grep '/vendor/bin'
+```
+
+`procfs`, `sysfs` and `debugfs` use `genfscon` path mappings rather than persistent per-inode labels. Adding a mapping only assigns a target type; the test domain still requires the corresponding allow rule and object class.[[5]](#references)[[6]](#references)[[9]](#references)
+
+```bash
+magiskpolicy --live 'genfscon proc /kallsyms u:object_r:proc_kallsyms:s0'
+magiskpolicy --live 'allow myexploit_t proc_kallsyms file { open read getattr }'
+```
+
+## Test another domain with `runcon`
+
+Changing only the requested context is insufficient. A successful `runcon` test needs (1) caller-to-target `process { transition setexec }`, (2) target-domain `entrypoint` access to the executable type, and (3) permission for the target to use inherited ADB descriptors, sockets and terminal devices. The Linux UID is inherited separately, so `runcon ... id` can report UID 0 in a restricted SELinux domain.[[9]](#references)
+
+```bash
+magiskpolicy --live 'allow magisk system_app process { transition dyntransition setexec }'
+magiskpolicy --live 'allow system_app toolbox_exec file { entrypoint execute read open getattr map }'
+magiskpolicy --live 'allow system_app adbd fd use'
+magiskpolicy --live 'allow system_app adbd unix_stream_socket { read write }'
+magiskpolicy --live 'allow system_app devpts chr_file { read write open getattr ioctl }'
+adb shell su -c 'runcon u:r:system_app:s0 id'
+```
+
+Use the resulting context to answer one narrow question at a time, such as whether `cameraserver` can open a GPU node or an app domain can read a specific procfs object. Follow every new AVC rather than broadening the domain globally.[[9]](#references)
+
+## Live policy changes with `magiskpolicy`
+
+`magiskpolicy` parses binary/runtime policy and `--live` immediately loads the result into the kernel. Its policy language supports `allow`, `deny` (removing matching allow bits), audit controls, per-type permissive/enforcing state, new types and attributes, transitions, `genfscon`, and ioctl extended permissions.[[6]](#references)[[9]](#references)
+
+```bash
+magiskpolicy --live 'allow shell proc_mem file { open read write getattr }'
+magiskpolicy --live 'deny untrusted_app shell_data_file file execute'
+magiskpolicy --live 'auditallow untrusted_app app_data_file file { read write }'
+magiskpolicy --live 'permissive untrusted_app'
+magiskpolicy --live 'enforce untrusted_app'
+```
+
+### Dedicated exploit-testing domain
+
+Prefer a dedicated domain over making `shell`, `untrusted_app`, or the whole device permissive. The executable label becomes the transition trigger: when `shell` executes a file labeled `myexploit_exec_t`, the `type_transition` selects `myexploit_t`. Add only the resources the PoC needs, then inspect the domain's AVCs.[[6]](#references)[[9]](#references)
+
+
+Create a minimal custom transition
+
+```bash
+magiskpolicy --live 'type myexploit_t domain'
+magiskpolicy --live 'permissive myexploit_t'
+magiskpolicy --live 'type myexploit_exec_t file_type'
+magiskpolicy --live 'type_transition shell myexploit_exec_t process myexploit_t'
+magiskpolicy --live 'allow shell myexploit_t process transition'
+magiskpolicy --live 'allow shell myexploit_exec_t file { open read getattr execute }'
+magiskpolicy --live 'allow myexploit_t myexploit_exec_t file entrypoint'
+magiskpolicy --live 'allow myexploit_t shell_data_file file { open read write map getattr }'
+adb shell su -c 'chcon u:object_r:myexploit_exec_t:s0 /data/local/tmp/exploit_poc'
+adb shell /data/local/tmp/exploit_poc
+```
+
+
+
+### Fine-grained ioctl filtering
+
+A basic `chr_file ioctl` allow can still be denied by SELinux extended permissions. Grant only the ioctl request values required by the driver PoC; `*` (equivalent to `0x0000-0xFFFF`) removes that fine-grained restriction for the selected source/target/class and is appropriate only for disposable testing environments.[[6]](#references)[[9]](#references)
+
+```bash
+magiskpolicy --live 'allow shell gpu_device chr_file { open read write ioctl }'
+magiskpolicy --live 'allowxperm shell gpu_device chr_file ioctl { 0x6601 0x6602 }'
+# Broad laboratory-only alternative:
+magiskpolicy --live 'allowxperm shell gpu_device chr_file ioctl *'
+```
+
+Live edits disappear after reboot or policy replacement. For repeatable Magisk testing, place reviewed statements in `/data/adb/modules//sepolicy.rule` so Magisk merges them during boot; avoid wildcard rules and keep the module disabled outside the lab.[[9]](#references)
+
+```text
+allow my_daemon system_file file { open read getattr }
+allow my_daemon init unix_stream_socket connectto
+```
+
+## Kernel-space injection: KernelSU
+
+KernelSU performs its built-in SELinux changes in kernel code against the active `policydb`. Its current rules create a permissive `su` domain, assign trusted/network attributes, grant broad access and ioctl xperms, and replace the active policy pointer after updating the policy structures. This differs from `magiskpolicy --live`, which loads a patched policy through the normal runtime-policy path.[[7]](#references)[[9]](#references)
+
+Because these mechanisms intentionally weaken mandatory access control, treat any unauthorized access to a root-framework policy channel as a sandbox-break amplifier: it can expose device nodes, Binder/Unix sockets, procfs/sysfs data, cross-domain tracing and privileged executable transitions even when the attacker already has UID 0.[[7]](#references)[[9]](#references)
+
+## References
+
+- [1] [AOSP `seapp_contexts` mapping and precedence](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/main/private/seapp_contexts)
+- [2] [AOSP `mac_permissions.xml` signing identity to `seinfo` mapping](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/main/private/mac_permissions.xml)
+- [3] [Android Open Source Project - Validate SELinux policy and analyze denials](https://source.android.com/docs/security/features/selinux/validate)
+- [4] [AOSP `file_contexts` matching and `restorecon` use](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/main/private/file_contexts)
+- [5] [AOSP `genfs_contexts` pseudo-filesystem labels](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/main/private/genfs_contexts)
+- [6] [Magisk tools documentation - `magiskpolicy`](https://topjohnwu.github.io/Magisk/tools.html#magiskpolicy)
+- [7] [KernelSU SELinux policy injection source](https://github.com/tiann/KernelSU/blob/main/kernel/selinux/rules.c)
+- [8] [setools-android](https://github.com/xmikos/setools-android)
+- [9] [Android SELinux Internals Part II - Domains, Denials, and Bypass with Root Tools](https://8ksec.io/android-selinux-internals-part-ii)
+
+{{#include ../../banners/hacktricks-training.md}}