Skip to content
benjamindainesPublic

About

Tool based on custota-selinux for fairly comprehensive modification of Android SELinux policies

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

27 Commits

Folders and files

Repository files navigation

NOTE:

It is recommended to run SEPcheck before making any changes, to make sure the .cil files in your ROM actually compile. It's fairly likely that they won't. If they don't, run SEPsani to clean them of duplicate entries across multiple partitions. Run SEPcheck again after, it should pass at that point.. hopefully.

This toolset has only been tested during the process of building the BenOS ROM, I assume it will work generally, let me know if it doesn't or feel free to fork and submit PRs with changes that make it work more universally.

Good luck, have fun. Make frequent backups. Keeping working backups is the absolute best advice, but the advice at the bottom of the README is almost as good. Be sure to read it ;)

SEPinject

usage: SEPinject [-h] [--te RULES.te] [--remove-te REMOVE.te] [--seapp SEAPP.txt]
                 [--remove-seapp REMOVE_SEAPP.txt] [--file-contexts FILE_CTX.txt]
                 [--property-contexts PROP_CTX.txt] [--service-contexts SVC_CTX.txt]
                 [--hwservice-contexts HWSVC_CTX.txt] [--policy POLICY_FILE [POLICY_FILE ...]]
                 [--system-selinux DIR] [--vendor-selinux DIR] [--rom-root DIR] [--dry-run]
                 [--dump-json OUT.json] [--skip-binary] [--skip-cil] [--skip-seapp] [--skip-file-contexts]
                 [--skip-property-contexts] [--skip-service-contexts] [--skip-hwservice-contexts] [--skip-sha256]
                 [--skip-neverallow-check] [--plat-cil-only] [--no-auto-coredomain] [--coredomain TYPE]
                 [--vendor-attr-add ATTR=TYPE1,TYPE2] [--validate] [--validate-full] [--rebuild-neverallows]
                 [--rebuild-mods-marker MARKER] [--yes] [--recreate-mlsconstrains] [--recreate-mls-domain DOMAIN]
                 [--check-mlsconstrains]

Inject SELinux policy rules from a .te file into Android ROM policy files.

options:
  -h, --help            show this help message and exit
  --te RULES.te         .te file with SELinux policy rules to ADD (allow, type, genfscon, typeattribute, ...)
  --remove-te REMOVE.te
                        .te file with rules to REMOVE from the policy. Same syntax as --te but each statement is
                        prefixed with remove_: remove_allow, remove_type, remove_genfscon, remove_permissive,
                        remove_typeattribute
  --seapp SEAPP.txt     File with seapp_contexts lines to append to plat_seapp_contexts
  --remove-seapp REMOVE_SEAPP.txt
                        File with seapp_contexts lines to REMOVE from plat_seapp_contexts (exact line match). Run
                        before --seapp to replace stale entries.
  --file-contexts FILE_CTX.txt
                        File with file_contexts lines to append to plat_file_contexts
  --property-contexts PROP_CTX.txt
                        File with property_contexts lines to append to plat_property_contexts (system) and/or
                        vendor_property_contexts. Format: "persist.foo.bar u:object_r:mytype:s0 exact string"
  --service-contexts SVC_CTX.txt
                        File with service_contexts lines to append to plat_service_contexts. Format:
                        "my.service.name u:object_r:my_service:s0"
  --hwservice-contexts HWSVC_CTX.txt
                        File with hwservice_contexts lines to append to plat_hwservice_contexts or
                        vendor_hwservice_contexts. Format: "vendor.foo@1.0::IFoo/default
                        u:object_r:hal_foo_hwservice:s0"
  --policy POLICY_FILE [POLICY_FILE ...]
                        One or more binary sepolicy files to patch directly
  --system-selinux DIR  Path to system/etc/selinux directory (for CIL, seapp_contexts, file_contexts, sha256
                        update)
  --vendor-selinux DIR  Path to vendor/etc/selinux directory (for vendor sidecar sha256 update)
  --rom-root DIR        Root of an unpacked ROM; auto-discovers all targets
  --dry-run             Show what would be done without writing any files
  --dump-json OUT.json  Write parsed binary-patch rules to a JSON file
  --skip-binary         Skip binary sepolicy patching (CIL/context only)
  --skip-cil            Skip plat_sepolicy.cil patching
  --skip-seapp          Skip plat_seapp_contexts patching
  --skip-file-contexts  Skip plat_file_contexts patching
  --skip-property-contexts
                        Skip property_contexts patching
  --skip-service-contexts
                        Skip service_contexts patching
  --skip-hwservice-contexts
                        Skip hwservice_contexts patching
  --skip-sha256         Skip SHA-256 recomputation
  --skip-neverallow-check
                        Skip the pre-flight CIL neverallow conflict scan. By default, the tool checks whether any
                        --te allow rules conflict with existing CIL neverallow rules and offers to rewrite them.
  --plat-cil-only       When running the neverallow conflict scan, only process plat_sepolicy.cil (the system
                        partition CIL). By default the scan also covers vendor_sepolicy.cil and
                        system_ext_sepolicy.cil where present, matching the scope of binary policy patching.
  --no-auto-coredomain  Disable automatic coredomain attribution for new domains. By default, any type declared
                        as a domain (or targeted by a process-class type_transition) is automatically added to
                        the coredomain typeattributeset in plat_sepolicy.cil. This is required to satisfy Treble
                        plat-vs-vendor neverallows for new plat-side domains. Disable only if you know what you
                        are doing.
  --coredomain TYPE     Explicitly add this type name to the coredomain typeattributeset in plat_sepolicy.cil.
                        Can be passed multiple times. Useful when --no-auto-coredomain is set, or when you want
                        to add a type to coredomain without declaring it via --te.
  --vendor-attr-add ATTR=TYPE1,TYPE2
                        Augment a typeattributeset in vendor_sepolicy.cil. Format: --vendor-attr-add
                        ATTR=TYPE1,TYPE2. The specified types are added to the named attribute set in vendor's
                        CIL without re-declaring the types (which would cause a duplicate-declaration compile
                        error). Use this when a new plat-side type needs membership in a vendor-defined attribute
                        set.
  --validate            Run policy validation in surgical mode: scan all CIL files under --rom-root for broken
                        sepinject artifacts (nested aux refs, dangling aux references, orphaned/empty/duplicate
                        aux decls, unrecoverable blocks) and offer to repair each one by rebuilding from the
                        audit-trail baseline. Standalone mode only — must be combined with --rom-root; combinable
                        with --dry-run for a no-op preview. Backs up every touched CIL file to <rom-
                        root>/sepinject_validate_backup_<TS>/ before making any change (skipped under --dry-run).
  --validate-full       Like --validate, but rebuild EVERY sepinject rewrite block in every targeted CIL file
                        from baseline — even ones that currently look well-formed. Use this when the policy is
                        badly corrupted and a from-scratch rebuild is preferable to per-issue surgery. Implies
                        --validate.
  --rebuild-neverallows
                        Recovery mode: scan the same fixed set of CIL files the normal pre-flight check already
                        targets under --rom-root (plat_sepolicy.cil, system_ext_sepolicy.cil,
                        vendor_sepolicy.cil, and plat_pub_versioned.cil — NOT a recursive glob), look for the
                        marker line '; ~~~:BEGIN_MODS:~~~', extract every `(allow ...)` rule below the marker,
                        and re-run the pre-flight neverallow conflict check against the FULL set of neverallows
                        in those CIL files. Conflicts are rewritten via the same carve-out / perm-drop machinery
                        used by the normal patch flow. Standalone — requires --rom-root, accepts --dry-run /
                        --skip-sha256 / --plat-cil-only / --yes. Backs up every targeted CIL into <rom-
                        root>/sepinject_rebuild_neverallows_backup_<TS>/ before any write. Assumes the user has
                        already manually removed prior sepinject_aux_* rewrites and restored the original
                        commented neverallow lines as live statements.
  --rebuild-mods-marker MARKER
                        Override the marker line used by --rebuild-neverallows to find the start of user mods
                        (default: '; ~~~:BEGIN_MODS:~~~')
  --yes, --assume-yes   Auto-approve the interactive prompt issued by --rebuild-neverallows / --recreate-
                        mlsconstrains (and the --check-mlsconstrains pre-flight). Use with care — in recovery
                        scenarios you may want to review each rewrite first.
  --recreate-mlsconstrains
                        Recovery mode, the MLS analogue of --rebuild-neverallows: scan the same fixed set of CIL
                        files under --rom-root (plat_sepolicy.cil, system_ext_sepolicy.cil, vendor_sepolicy.cil,
                        plat_pub_versioned.cil — NOT a recursive glob), look for the marker line ';
                        ~~~:BEGIN_MODS:~~~', extract every `(allow ...)` below it, and check those against the
                        FULL set of mlsconstrains. A constraint that would (or could) DENY a mod allow at runtime
                        is widened with an `(or ORIG (eq t1 sepinject_mlsaux_*))` exemption for the offending
                        subject domain(s). Standalone — requires --rom-root, accepts --dry-run / --skip-sha256 /
                        --plat-cil-only / --yes and the shared --rebuild-mods-marker. Backs up every targeted CIL
                        into <rom-root>/sepinject_recreate_mlsconstrains_backup_<TS>/ before any write.
  --recreate-mls-domain DOMAIN
                        Like --recreate-mlsconstrains, but only widen constraints that block the single source
                        domain DOMAIN — the mod allow rules are filtered to rule.src == DOMAIN before the scan.
                        Use this to exempt one domain at a time instead of punching holes in every constraint for
                        every mod subject at once. Same standalone requirements/flags as --recreate-
                        mlsconstrains.
  --check-mlsconstrains
                        During a normal --te patch run, ALSO scan for mlsconstrain conflicts (constraints that
                        would deny an injected allow at runtime) and offer to widen them, mirroring the
                        neverallow pre-flight. This is OPT-IN (the neverallow pre-flight is opt-out) on purpose:
                        unlike neverallow conflicts, mlsconstrain conflicts do NOT break a CIL recompile, so
                        auto-relaxing MLS on every run would silently loosen policy. Enable it only when you
                        specifically want MLS constraints considered.

sepinject.py — Inject or remove SELinux policy rules from pre-compiled
Android ROM binary policy files (sepolicy / precompiled_sepolicy) without
recompiling from source.

Supports patching:
  • vendor_boot/cpio_tree/sepolicy
  • vendor/fs_tree/etc/selinux/precompiled_sepolicy
  • system/fs_tree/system/etc/selinux/precompiled_sepolicy  (if present)

Supported .te rule types (--te, adding rules):
  allow, auditallow, dontaudit, neverallow (skipped with warning),
  permissive, type (declaration), attribute (declaration),
  type_transition, typeattribute, genfscon,
  mlstrustedsubject, mlstrustedobject (CIL-only sugar for
    `typeattribute X mlstrustedsubject;` — accepts one or more
    type names: `mlstrustedsubject foo, bar;`)

AOSP m4 macro expansion:
  Function-style te_macros (init_daemon_domain, domain_auto_trans,
  set_prop, get_prop, binder_use, binder_call, binder_service,
  unix_socket_connect) are expanded textually before parsing.

  AOSP global_macros — permission groupings (rx_file_perms, r_file_perms,
  w_file_perms, ra_file_perms, rw_file_perms, rwx_file_perms,
  create_file_perms, r_dir_perms, w_dir_perms, ra_dir_perms, rw_dir_perms,
  create_dir_perms, r_ipc_perms, w_ipc_perms, rw_ipc_perms,
  create_ipc_perms, rw_socket_perms, rw_socket_perms_no_ioctl,
  create_socket_perms, create_socket_perms_no_ioctl,
  rw_stream_socket_perms, create_stream_socket_perms) and class groupings
  (capability_class_set, file_class_set, devfile_class_set,
  notdevfile_class_set, dir_file_class_set, dgram_socket_class_set,
  stream_socket_class_set, unpriv_socket_class_set,
  network_socket_class_set, ipc_class_set, plus the global_capability*
  variants) — are flattened into their concrete perm/class sets, with
  recursive expansion (rx_file_perms -> r_file_perms x_file_perms ->
  final perms).  Both bare usage and usage inside brace groups work.

Supported removal directives (--remove-te):
  Same syntax as --te but prefixed with remove_:
  remove_allow src tgt:cls { perms };
  remove_genfscon fs "/path";
  remove_permissive type;
  remove_type type;           (CIL only — binary type removal not supported)
  remove_typeattribute type attr;
  remove_mlstrustedsubject type[, type ...];   (CIL only)
  remove_mlstrustedobject type[, type ...];    (CIL only)

Usage:
  # Add rules only
  python3 sepinject.py --te rules.te --rom-root /path/to/rom

  # Remove rules only
  python3 sepinject.py --remove-te remove.te --rom-root /path/to/rom

  # Remove old rules then add new ones (safe replace pattern)
  python3 sepinject.py --remove-te old_rules.te --te new_rules.te --rom-root /path/to/rom

  # Dry run to preview changes
  python3 sepinject.py --te rules.te --remove-te remove.te --dry-run

The tool compiles a small C helper (sepatch_helper) against the system
libsepol on first run and caches it at ~/.cache/sepinject/sepatch_helper.

SEPreap

Still won't catch everything. Take the output file of this and run it through SEPwalk.

usage: SEPreap [-h] [--rom-root ROM_ROOT] [-d] [-D FILE] [--domain TYPE] [--domain-src TYPE] [--domain-tgt TYPE]
               [--cil] [-k] [-o OUTPUT] [-v]
               [logs ...]

Reap AVC denials from logs into .te rules, grouped by domain, paste-ready for SEPinject.

positional arguments:
  logs                  dmesg / logcat / audit.log files (default: stdin). Use '-' for stdin explicitly.

options:
  -h, --help            show this help message and exit
  --rom-root ROM_ROOT   Root of an extracted ROM (system/fs_tree/, vendor/fs_tree/, system_ext/fs_tree/). When
                        given, source/target types are checked against the ROM CIL.
  -d, --dontaudit       Classify noise-table denials into dontaudit rules instead of allow. OFF by default.
  -D, --dontaudit-rules FILE
                        Extra noise rules appended to the built-in table (one 'ttype/tclass:perm' per line). Implies
                        -d.
  --domain TYPE         Only reap denials where TYPE appears in EITHER the source or target context. Repeatable;
                        accepts globs (e.g. --domain 'hal_*'). A 'self' target counts as its source type.
  --domain-src TYPE     Like --domain but pinned to the source (subject) context only. Repeatable; accepts globs.
  --domain-tgt TYPE     Like --domain but pinned to the target (object) context only. Repeatable; accepts globs.
  --cil                 Also emit a CIL form of each rule beneath the .te line (for direct secilc / SEPclean
                        workflows).
  -k, --keep-cats       Annotate each rule with its scontext MLS categories.
  -o, --output OUTPUT   Write report here instead of stdout.
  -v, --verbose         Print progress to stderr.

SEPclean

usage: SEPclean [-h] [-o OUTPUT] [--relocate-neverallows] [--relocate-mlsconstrains] [--dry-run] [--force] input

Clean & regroup a sepinject CIL.

positional arguments:
  input

options:
  -h, --help            show this help message and exit
  -o, --output OUTPUT   write cleaned output here and do NOT rename input (default: rename input to
                        <input>.unclean and write the cleaned result under the input's original name)
  --relocate-neverallows
                        pull active rewritten neverallows from above the marker down into the mods region
  --relocate-mlsconstrains
                        pull active rewritten mlsconstrains (those carrying a sepinject_mlsaux_ exemption) from
                        above the marker down into the mods region
  --dry-run             validate and report, but write nothing
  --force               allow overwriting an existing <input>.unclean

SEPsani

usage: SEPsani [-h] [--plat PLAT] [--ppv PPV] [--vendor VENDOR] [--system-ext SYSTEM_EXT] [--dry-run] [rom_root]

sanitize_cil.py

Clean up ROM-shipped CIL files so they can be re-compiled by secilc.

Background
----------
This ROM's CIL files contain structural duplicates that prevent fresh
compilation by secilc.  The precompiled_sepolicy binary was produced by
Google's build pipeline (which uses custom CIL combiner tooling that
handles these duplicates) — but `secilc` on Ubuntu/Linux refuses them.

The duplicates appear to fall into a few specific categories:

  (1) Same `(type X)` declared in both plat_sepolicy.cil and
      plat_pub_versioned.cil.  The ppv file is supposed to hold only
      VERSIONED types (like adbd_31_0), but here it also redeclares
      UNVERSIONED ones that plat owns.  Solution: remove duplicates
      from ppv, since plat is the canonical owner.

  (2) Same `(typeattribute X)` declared in both files.  Same fix.

  (3) Within plat_sepolicy.cil itself, `system_and_vendor_property_type`
      is declared twice.  The second occurrence is part of an explicit
      "workaround" block — but the type was already auto-declared earlier.
      Solution: comment out the second occurrence.

  (4) A handful of `(type X)` duplicates between plat and vendor_sepolicy.cil
      (e.g. `proc_cpu_alignment`).  These are vendor types that plat
      somehow also declares.  Solution: comment them out of vendor since
      plat owns them at the platform layer.

  (5) Some `(typeattributeset X ...)` lines may also conflict, especially
      if both files claim the same attribute as a complex S-expression.
      Solution: detect at compile time, address case by case.

Usage
-----
    python3 sanitize_cil.py /path/to/rom/

Where /path/to/rom/ is the directory containing system/, vendor/, and
system_ext/ subtrees.  The script will locate the CIL files itself.

Or pass paths explicitly:

    python3 sanitize_cil.py         --plat /path/.../plat_sepolicy.cil         --ppv /path/.../plat_pub_versioned.cil         --vendor /path/.../vendor_sepolicy.cil         --system-ext /path/.../system_ext_sepolicy.cil

A `.before_sanitize.bak` backup is made of each file before modification
(skipped if a backup already exists).  All removals are by COMMENTING
OUT the offending lines with a `; sanitize:` marker — never destructive.
Re-running is idempotent.

After running, you'll want to verify with secilc:

    secilc -M true -G -N -c 30 \
        plat_sepolicy.cil system_ext_sepolicy.cil \
        vendor_sepolicy.cil plat_pub_versioned.cil \
        -o /tmp/check.bin

If new errors surface, address them and re-run.

positional arguments:
  rom_root              ROM root containing system/, vendor/, system_ext/

options:
  -h, --help            show this help message and exit
  --plat PLAT           Path to plat_sepolicy.cil
  --ppv PPV             Path to plat_pub_versioned.cil
  --vendor VENDOR       Path to vendor_sepolicy.cil
  --system-ext SYSTEM_EXT
                        Path to system_ext_sepolicy.cil
  --dry-run             Report what would change without writing

SEPcheck

Nothing fancy, just a bash script that calls secilc. Installer script places it in ~/.local/bin/ along with the other binaries. Edit the file in this directory and re-run install.sh, or edit SEPcheck in ~/.local/bin/ with the relevant directory paths for your env.

SEPwalk

Feed it your .te file and --rom-root and it will suggest additional rules you will need. Not perfect, does help tho. This is the major area that could use improvement.

Can be used as such: $ SEPwalk --te your-te.te --rom-root path/to/rom/root >> your-te.te suggested additional rule will be printed ready to be injected with SEPinject without any additional editing. Run the above command a few times too, until it stops giving additional suggestions or beings repeating itself. At that point, shove it into your policy and give the wheel a spin. 🤞 Check dmesg and logcat for avc denials. If you're still getting denials after you've added the necessary allows, you're proably running into a mlsconstrain or neverallow. While neverallows should be handled cleanly and automatically, one can still find themselves in the situation where it's best to go back to the original neverallow, delete the sepinject carve-outs, and run ``--rebuild-neverallows, you may also find yourself in the position where the best thing to do is delete the entire sepolicy above your changes (you did save a copy of the post-SEPsani` condition, yes?) and re-paste a known working, clean state, then run `--rebuild-neverallows`. I've never had to start completely over, don't panic when you burn your policy :)

usage: sepolwalker [-h] --te TE --rom-root ROM_ROOT [-o OUTPUT] [-v]

Walk an Android SELinux policy to find prerequisite rules required to make a
given .te file work.

options:
  -h, --help           show this help message and exit
  --te TE              The .te source file describing the rules you want.
  --rom-root ROM_ROOT  Root of an extracted ROM (must contain system/fs_tree/,
                       vendor/fs_tree/, system_ext/fs_tree/).
  -o, --output OUTPUT  Write the report to this file instead of stdout.
  -v, --verbose        Print extra progress info to stderr.

About

Tool based on custota-selinux for fairly comprehensive modification of Android SELinux policies

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages