顯示具有 policy 標籤的文章。 顯示所有文章
顯示具有 policy 標籤的文章。 顯示所有文章

2013年5月24日 星期五

SEforAndroid

Policy

1. Policy sources are located at "external/sepolicy". There may also be policy configuration files to enable specific device features under device/<vendor>/<device>/sepolicy directories

2. The policy consists of source files used to generate the SELinux kernel policy file, a file_contexts configuration, a property_contexts configuration, a seapp_contexts configuration, and a mac_permissions.xml configuration.
  • The file_contexts configuration is used to label files at build time (e.g. the system partition) and at runtime (e.g. device nodes, service socket files, /data directories created by init.rc, ...). The file_contexts configuration content of AOSP and SEforAndroid are a little different. It will be used by external/libselinux/src/android.c and external/libsepol/src/module.c.
  • The property_contexts configuration is used to specify the security context of Android properties for permission checking purposes.  The property_contexts configuration content of AOSP and SEforAndroid are a little different. It will be used by system/core/init/init.c and frameworks/base/services/java/com/android/server/DevicePolicyManagerService.java.
  • The seapp_contexts configuration is used to label app processes and app package directories. The seapp_contexts configuration content of AOSP and SEforAndroid are a little different. It is used by external/libselinux/src/android.c and frameworks/base/services/java/com/android/server/DevicePolicyManagerService.java.
  • The mac_permissions.xml configuration is the middleware MAC policy. The mac_permissions.xml configuration content of AOSP and SEforAndroid are a little different. It is used by frameworks/base/services/java/com/android/server/DevicePolicyManagerService.java, external/sepolicy/tools/setool/src/com/seandroid/tools/PolicyParser.java, frameworks/base/services/java/com/android/server/pm/SELinuxMMAC.java and some *.py files.
  • The property_contexts, seapp_contexts, and mac_permissions.xml configurations are unique to SE for Android (i.e. they were not part of the regular SELinux policy).

3.Device-specific policy can be specified by defining BOARD_SEPOLICY_DIRS, BOARD_SEPOLICY_UNION and/or BOARD_SEPOLICY_REPLACE, BOARD_SEPOLICY_IGNORE variables in a BoardConfig.mk file under the device/<vendor>/<device> or vendor/<vendor>/<device> directories.
  • BOARD_SEPOLICY_UNION is a list of files that will be "unioned", IE concatenated, at the END of their respective file in external/sepolicy. Note, to add a unique file you would use this variable.
  • BOARD_SEPOLICY_REPLACE is a list of files that will be used instead of the corresponding file in external/sepolicy.
  • BOARD_SEPOLICY_DIRS contains a list of directories to search for BOARD_SEPOLICY_UNION and BOARD_SEPOLICY_REPLACE files. Order matters in this list.
  • BOARD_SEPOLICY_IGNORE is a list of paths (directory + filename) of files that are not to be included in the resulting policy. This list is passed to filter-out to remove any paths you may want to ignore. This is useful if you have numerous config directories that contain a file and you want to NOT include a particular file in your resulting policy file, either by UNION or REPLACE.
4. SELinux kernel policy is presently compiled as part of the Android build and added to the ramdisk image so that it can be loaded by init very early in boot, before mounting the system partition.

5.Once the data partition has been mounted, policy can be reloaded from /data/security by placing policy files under /data/security and setting the selinux.reload_policy property to 1 (setprop selinux.reload_policy 1). This will trigger a reload of policy by init, which will also restart ueventd and installd so that they can reload the policy configuration files relevant to their operation.

6.The initialisation or policy reload process will always check for a policy at /data/security/sepolicy first and then if not present at /sepolicy. 

7.The policy can then be compiled by checkpolicy(8). For reference, the policy text file is built and placed in: 
out/target/product/<device>/obj/ETC/sepolicy_intermediates/policy.conf

8. The *.te files are the policy module definition files. These are the same format as the standard reference policy and are expanded by the m4 macros. There is (generally) one .te file for each domain/service defined for the device and will contain all the required allow, type_transition etc. rules. It will also call any te_macros to access other domains resources (e.g. init_daemon_domain, binder_call).

9. seapp_contexts --
 This file is loaded and sorted into memory automatically on first use of one of the following SE for Android libselinux functions that are called by the SE for Android enabled services:
selinux_android_setcontext - Computes process security contexts.selinux_android_setfilecon2 - Computes file/directory security contexts.
selinux_android_seapp_context_reload will also reload this file.

Above functions are implemented in external/libselinux/src/android.c

Input selectors from seapp_contexts file:
  • isSystemServer (boolean)
  • user (string)
  • seinfo (string)
  • name (string) - A package name e.g. com.example.demo
  • sebool (string) - The boolean must be ‘active’ (enabled/true)

isSystemServer=true can only be used once. An unspecified isSystemServer defaults to false.

An unspecified string selector will match any value.

A user string selector that ends in * will perform a prefix match.

user=app_* will match any regular app UID.

user=isolated will match any isolated service UID.

All specified input selectors in an entry must match (i.e. logical AND).

Matching is case-insensitive.

Precedence rules:
1) isSystemServer=true before isSystemServer=false.
2) Specified user= string before unspecified user= string.
3) Fixed user= string before user= prefix (i.e. ending in *).
4) Longer user= prefix before shorter user= prefix.
5) Specified seinfo= string before unspecified seinfo= string.
6) Specified name= string before unspecified name= string.
7) Specified sebool= string before unspecified sebool= string.

Outputs:
domain (string) - The type component of a process context.
type (string) - The type component of a file/directory context.level
From (string; one of none, all, app, or user) - A level that will be automatically computed based on the parameter.
level (string) - A predefined level (e.g. s0:c1022.c1023)

Only entries that specify domain= will be used for app process labeling.

Only entries that specify type= will be used for app directory labeling.

levelFrom=user is only supported for _app or _isolated UIDs.

levelFrom=app or levelFrom=all is only supported for _app UIDs.

level may be used to specify a fixed level for any UID.

10. file_contexts --
Contains default file contexts for setting the filesystem as standard SELinux. The format of this file is defined in file_contexts. The file is installed by default in the root directory. SE for Android services (such as restorecon) will first check for this file at (this is where updated files should be placed): /data/security/file_contexts



This file becomes the policies ./contexts/files/file_contexts file and is built from entries in the ./modules/active/file_contexts.template file as explained above and shown in above picture. It is then used by the file labeling utilities to ensure that files and directories are labeled according to the policy.

Example file_contexts contents:
#root
/                  u:object_r:rootfs:s0

#Data File
/adb_keys          u:object_r:rootfs:s0
/defcult.prop      u:object_r:rootfs:s0

#Executables       
/init              u:object_r:rootfs:s0
/sbin(/.*)?        u:object_r:rootfs:s0

#Devices
/dev(/.*)?         u:object_r:device:s0
/dev/alarm         u:object_r:alarm_device:s0
/dev/audio.*       u:object_r:audio_device:s0

11. property_contexts --
Contains default contexts to be applied to Android property services as discussed in the property_contexts file section. The file is installed by default in the root directory. The SE for Android initialisation / reload process will first check for this file at (this is where updated files should be placed):
/data/security/property_contexts

This file holds property names and their contexts that will be applied by SELinux when applications are loaded. The property names reflect the 'white list' of Android property entries that are also built into the system (see system/core/init/property_service.c and init.c) however there are also additional property entries for applications that require specific contexts to be set.

Each line within the property contexts file is as follows:
property_key context

Where:
property_key The key used to obtain the context that may contain '*' for wildcard matching.
context The security context that will be applied to the object.

Example of property_contexts
##########################
# property service keys
#
 
net.rmnet0              u:object_r:radio_prop:s0
net.gprs                u:object_r:radio_prop:s0
net.ppp                 u:object_r:radio_prop:s0
net.qmi                 u:object_r:radio_prop:s0
net.lte                 u:object_r:radio_prop:s0
net.cdma                u:object_r:radio_prop:s0
gsm.                    u:object_r:radio_prop:s0
persist.radio           u:object_r:radio_prop:s0
net.dns                 u:object_r:radio_prop:s0
sys.                    u:object_r:system_prop:s0
service.                u:object_r:system_prop:s0
wlan.                   u:object_r:system_prop:s0
dhcp.                   u:object_r:system_prop:s0
debug.                  u:object_r:shell_prop:s0
log.                    u:object_r:shell_prop:s0

Build Tools

The kernel policy is compiled using checkpolicy(8) via the external/sepolicy/Android.mk file. There are also a number of SE for Android specific tools used to assist in policy configuration that are described in Policy Build Tools, with a summary as follows:
  • checkfc - Used to parse the file_contexts file against the binary policy sepolicy. This is to ensure all file contexts are valid for the policy. There is a -p option that is used to validate the contexts defined in the property_contexts file. Example validating file_contexts file:
    checkfc out/target/product/generic/root/sepolicy out/target/product/generic/root/file_contexts
    

  • Example validating property_contexts file:
    checkfc -p out/target/product/generic/root/sepolicy out/target/product/generic/root/property_contexts
  • checkseapp - Used to parse the seapp_contexts file against the binary policy sepolicy. This is to ensure policy related information is valid (e.g. checks booleans, types, levels etc.).
  • insertkeys.py - Used to replace keywords in the signature sections of the mac_permissions.xml and mmac_types.xml files with keys obtained frompem files. This uses information contained in the external/sepolicy/keys.conf file that is detailed in the keys.conf section. This utility will also strip files of comments.
  • setool - This is not used by the actual build process but assists in generating new entries for the mac_permissions.xml file. It will extract permissions from one or more packages with their signatures then generate the package sections. Its output may need to be modified before inclusion in the master file as detailed in the setool section.

Modifying and Reloading Policy

This is covered at SEforAndroid - Policy in detail. This section gives a brief overview:
  • Modify the required policy source files, then regenerate the kernel policy file by:
make sepolicy
  • Copy the policy file to the device:
adb push out/target/product/<device>/root/sepolicy /data/security
  • Then load the new policy by:
adb shell su 0 setprop selinux.reload_policy 1

Middleware MAC

  • Install-time MAC (merged to seandroid),
  • Permission revocation (revoke-perms),
  • Intent MAC (intent_mac).

Install-time MAC

1. This mechanism applies an install-time check of app permissions against a MAC policy configuration (found in external/sepolicy/mac_permissions.xml in the source tree and as /system/etc/security/mac_permissions.xml on the system image).

2. The main code for the service is 
frameworks/base/services/java/com/android/server/pm/SELinuxMMAC.java

3. The persist.mmac.enforce system property controls whether the MAC restrictions are enforced; this can be set via SEAdmin app or via setprop.

4. The setool program can be used to generate policy stanzas for mac_permissions.xml, or to check whether a given apk would violate a given mac_permissions.xml configuration.
setool --build whitelist /path/to/foo.apk
setool --policy /path/to/mac_permissions.xml /path/to/foo.apk

5. Install-time MMAC policy that checks whether app permissions are allowed or not. If not allowed, the app cannot be installed or if the app is already installed before the updated policy, then the app cannot be run after the update.

Premission Revocation

1. A revoked permission list is maintained for each package and checked at runtime on permission checks. 

2. A revoked permissions configuration (found in external/mac-policy/revoke_permissions.xml in the source tree and as etc/security/revoke_permissions.xml on the system image) can specify revocation lists that are applied automatically on each boot.

3. Revoke permissions policy that checks whether the policy configured permissions on a package basis will be revoked at run time. If not allowed, that permission will be revoked (i.e. allow all unless specifically revoked). This is an optional policy and does not require any specific SELinux policy support.

4. The file that configures the policy is the revoke_permissions.xml and by default is installed at:
/system/etc/security/revoke_permissions.xml

5. The main code for the service is self contained in:
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java

Intent MAC

1. Intent MAC supports a white-list of Intents and the types of their sources and destinations.

2. Currently, we only protect delivery of Intents to Activities, Broadcast Receivers, and Services. Content Providers are not yet protected.

3. Intent MMAC policy that checks whether the policy configured app intents (on a package and/or signature basis) are allowed or not at run time. If not allowed, that intent will not be sent.

4. The files that configure policy are intent_mac.xml and mmac_types.xml and by default they are installed at: 
/system/etc/security/intent_mac.xml
/system/etc/security/mmac_types.xml

5. The main code for the service is
frameworks/base/core/java/andriod/content/pm/IntentMAC.java and MMACtypes.java


auditd Daemon


The majority of this text has been extracted from system/core/auditd/README that describes its configuration, however note that:
  • Kernel auditing is included by default when building the SE for Android supplied kernels (e.g. for goldfish kernel see thekernel/goldfish/arch/arm/configs/goldfish_arm7_defconfig file) and auditd daemon is also included by default (seebuild/target/product/core.mk - under the SELinux packages).
  • The audit daemon output is formatted so that ausearch(8) can be used to search for SELinux events.




reference:

2013年5月15日 星期三

SELinux Notes -- Part I, Overview

SELinux by Example: Using Security Enhanced Linux
By Frank Mayer,, Karl MacMillan,, David Caplan

=======================================================

  • SELinux access control is based on a security context associated with all system resources including processes. The security context contains three elements: user, role, and type identifiers. The type identifier is the primary basis for access control.
    In SELinux, type enforcement is the primary access control feature. Access is granted between subjects (that is, processes) and objects by specifying allow rules that have the subject's type (also called a domain type) as the source and the object's type as the target. Access is granted for specified object classes using a fine-grained set of permissions defined for each object class.
    One of the key benefits of type enforcement is the ability to control which programs may run with a given domain type, thereby allowing access control down to individual programs (rather than the less-secure level of a user). The capability for a program to enter into a domain (that is, run with a given process type) is called domain transition and is tightly controlled by SELinux allow rules. SELinux also allows domain transitions to occur automatically through the type_transition rule.

  • SELinux does not directly use the role identifiers in a security context for access control. Instead, all access is controlled based on types. Roles are used to associate the allowed domain types into which a process running on behalf of a user may transition. This allows sets of type enforcement allowed capabilities to be grouped together and authorized for a user as a role.

Type Enforcement Access Control


In SELinux, all access must be explicitly granted. SELinux allows no access by default, regardless of the Linux user/group IDs. Yes, this means that there is no default superuser in SELinux, unlike root in standard Linux.

An allow rule has four elements:
  • Source type(s) Usually the domain type of a process attempting access
  • Target type(s) The type of an object being accessed by the process
  • Object class(es) The class of object that the specified access is permitted
  • Permission(s) The kind of access that the source type is allowed to the target type for the indicated object classes
As an example, take the following rule:
allow user_t bin_t : file {read execute getattr};


The translation of this rule would be as follows:

A process with a domain type of user_t can read, execute, or get attributes for a file object with a type of bin_t.




Example: passwd program
allow passwd_t shadow_t : file {ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename};




In this example, we defined two types. The passwd_t type is a domain type intended for use by the password program. The shadow_t type is the type for the shadow password file. If we examine such a file on disk, we would see something like this:
# ls -Z /etc/shadow
-r----  root   root  system_u:object_r:shadow_t  shadow

Likewise, examining a process running the password program under this policy would yield this:
# ps -aZ
joe:user_r:passwd_t   16532 pts/0    00:00:00 passwd

The purpose of this rule is to give the passwd process' domain type (passwd_t) the access to the shadow's file type (shadow_t) needed to allow the process to move and create a new shadow password file.





Above figure shows an example of passwd program security in SELinux. The first rule is as follows:
allow user_t passwd_exec_t : file {getattr execute};

What this rule does is allow Joe's shell (user_t) to initiate an execve() system call on the passwd executable file (passwd_exec_t). The SELinux execute file permission is essentially the same permission as x access for files in standard Linux.


The next allow rules is
allow passwd_t passwd_exec_t : file entrypoint;

This rule provides entrypoint access to the passwd_t domain. The entrypoint permission is a rather valuable permission in SELinux. What this permission does is define which executable files (and therefore which programs) may "enter" a domain.



Let's now look at the final rule:
allow user_t passwd_t : process transition;

This is the first allow rule we have seen that did not provide access to file objects. In this case, the object class is process, meaning the object class representing processes. Recall that all system resources are encapsulated in an object class.




These three rules together provide the necessary access for a domain transition to occur. For a domain transition to succeed, all three rules are necessary; alone, none is sufficient. Therefore, a domain transition is allowed only when the following three conditions are true:

  1. The process' new domain type has enTRypoint access to an executable file type.
  2. The process' current (or old) domain type has execute access to the entry point file type.
  3. The process' current domain type has transition access to the new domain type.

When all three of these permissions are permitted in a TE policy, a domain transition may occur. Further, with the use of the entrypoint permission on executable files, we have the power to strictly control which programs can run with a given domain type. The execve() system call is the only way to change a domain type, giving the policy writer great control over an individual program's access to privilege, regardless of the user who may be invoking the program.


Default Domain Transitions: type_transition Statement



To support domain transitions occurring by default (as we want in the case of the password program), we need to introduce a new rule, the type transition rule (type_transition). This rule provides a means for the SELinux policy to specify default transitions that should be attempted if an explicit transition was not requested.

type_transition user_t passwd_exec_t : process passwd_t;

The syntax of this rule differs from the allow rule. There are still source and target types (user_t and passwd_exec_t, respectively) and an object class (process). However, instead of permissions, we have a third type, the default type (passwd_t).
Type_transition rules are used for multiple different purposes relating to default type changes.

The type_transition rule indicates that, by default on an execve() system call, if the calling process' domain type is user_t and the executable file's type is passwd_exec_t , a domain transition to a new domain type (passwd_t) will be attempted.


The type_transition rule allows the policy writer to cause default domain transitions to be initiated without explicit user input. This makes type enforcement less obtrusive to the user.


Role-Based Access Control (RBAC)


The RBAC feature of SELinux is built upon type enforcement; access control in SELinux is primarily via type enforcement. Roles limit the types to which a process may transition based on the role identifier in the process' security context.

We have added the role portion (user_r) of the security contexts for the processes depicted. We also added a new rule, specifically the role statement:
role user_r type passwd_t;

The role statement declares role identifiers and associates types with the declared role. The previous statement declares the role user_r (if it has not already been declared in the policy) and associates the type passwd_t with the role. What this association means is that the passwd_t type is allowed to coexist in a security context with the role user_r. Without this role statement, the new context joe:user_r:passwd_t could not be created, and the execve() system call would fail, even though the TE policy allows Joe's type (user_t) all the necessary access.

Role-based access control (RBAC) is a general security model that simplifies administration by assigning roles to users and then assigning permissions to those roles. RBAC in Security-Enhanced Linux (SELinux) acts as a layer of abstraction between the user and the underlying type-enforcement (TE) model, which provides highly granular access control but is not geared for ease of management.



Multilevel Security in SELinux (MLS)

The security level used by MLS systems is a combination of a hierarchical sensitivity and a set (including the null set) of nonhierarchical categories. These sensitivities and categories are used to reflect real information confidentiality or user clearances. In most SELinux policies, the sensitivities (s0, s1, ...) and categories (c0, c1, ...) are given generic names, leaving it to userspace programs and libraries to assign user-meaningful names. (For example, s0 might be associated with UNCLASSIFIED and s1 with SECRET.)
To support MLS, the security context is extended to include security levels as such these:
user:role:type:sensitivity[:category,...][-sensitivity[:category,...]]

Notice that the MLS security context must have at least one security level (which is composed of a single sensitivity and zero or more categories), but can include two security levels. These two security levels are called low (or current for processes) and high (or clearance for processes), respectively. If the high security level is missing, it is considered to be the same value as the low (the most common situation).

There are four dominance operators that can relate two MLS security levels are as follows:
dom:
(dominates) SL1 dom SL2 if the sensitivity of SL1 is higher or equal to the sensitivity of SL2, and the categories of SL1 are a superset of the categories of SL2.
domby:
(dominated by) SL1 domby SL2 if the sensitivity of SL1 is lower than or equal to the sensitivity of SL2, and the categories of SL1 are a subset of the categories of SL2.
eq:
(equals) SL1 eq SL2 if the sensitivity of SL1 and SL2 are equal, and the categories of SL1 and SL2 are the same set.
incomp:
(incomparable or noncomparable) SL1 incomp SL2 if the categories of SL1 and SL2 cannot be compared (that is, neither is a subset of the other).

SELinux Policy Server Architecture



In the policy server architecture, all manipulation and management of the overall system policy is controlled through the policy management server (PMS). The PMS is itself a userspace object manager in that it creates object classes representing policy resources and enforces a fine-grained access control policy over those resources.

With the PMS, you can now allow access to portions of the policy and limit access to others. For example, the SELinux policy can allow user management tools to add users and make role assignments, but not change type enforcement allow rules. Better yet, you can authorize a database server to change type enforcement (TE) rules relating to its object classes and types, but not those of the kernel. Internally, the PMS is designed to use another recent new feature of SELinux, loadable policy modules.


The second major function of the PMS is to split the system policy into kernel and user portions and load them respectively into the kernel security server and userspace security server (USSS). In this way, the kernel is not made aware of rules and object classes of concern only to userspace object managers. Userspace object managers query the USSS and not the kernel. AVCs in various userspace object managers register with the USSS (and not the kernel) for policy update and cache coherency functions.



SELinux Policy Language


The first section of a policy source file defines the object classes to the security server. This section also defines the permissions for each object class. For the kernel, these classes are directly related to kernel source files. In general, as an SELinux policy writer you would never change or modify the object class and permission definitions. 

The next section contains the type enforcement statements, which is by far the largest portion of an SELinux policy. This is the section that policy writers spend most of their time writing. It contains all the type declarations and all the TE rules (including all allow, type_transition, and other TE rules).

The next section of a policy source file contains the constraints. Constraints provide a means of further limiting the TE policy beyond what the TE rules permit. The multilevel security (MLS) policy, for example, is implemented as a set of constraints.

The last section of a policy file contains labeling specifications. All objects must be labeled with a security context for SELinux to enforce access control. This section tells SELinux how to treat filesystems for the purpose of labeling and contains the rules for labeling transient objects that are created at runtime. A separate related mechanism, called a file contexts file, is used to initialize the security context labeling of files, directories, and other objects on permanent filesystems.

Building and Installing Monolithic Policies


Above figure shows  a typical way that a policy is constructed.

Starting from the left side of this figure, you have the source files for the policy broken down into many tens of individual source modules. Compile the source policy using checkpolicy into a binary policy file, load_policy program is then used to load the binary policy file into the kernel, which then enforces access control based on the policy rules.
policy
Make policy.conf and policy.[ver] locally to test the compilation and check for error.
install
Do everything that make policy does plus install the binary policy file such that it will be loaded into the kernel at boot time and the policy configuration files.
load
Do everything that make policy does plus immediately load the binary policy file into the kernel as the active access control policy and install the file_contexts file.


2013年5月3日 星期五

SELinux Learning

SELinux Project

http://selinuxproject.org/page/NB_SEforAndroid_1


Breaking the Ice with SELinux

http://billauer.co.il/selinux-policy-module-howto.html


A step-by-step guide to building a new SELinux policy module


Writing SE Linux policy HOWTO


The Guide to Writing SELinux Policy


CentOS - SELinux HowTos


Fedora - SELinux



The_SELinux_Notebook_The_Foundations_3rd_Edition





========================================================================

Securing Android-Powered Mobile Devices Using SELinux

Integrating SELinux in Android
1) Android Doesn’t Support SELinux 
    – Selinux disabled in the Linux kernel 
        • requires a rooted device 
2) Android Doesn’t Have a Method or Tool for Loading the SELinux Policy 
    – Not loading the policy on boot or init process
        • added three new commands to init.rc 
    – Loadpolicy 、chcon 、context 
3) Creating a Custom SELinux Policy for Android 
    – The default SELinux reference policy is irrelevant on Android:
        • it assumes a Linux standard base layout
        • it’s too big for an embedded system. 
    – Solutions
        • construct a policy without using the reference policy .
        • Remove irrelevant modules (Apache)
4) Android’s File System Doesn’t Support Extended Attributes 
    – yaffs2 doesn’t support extended attributes (xattrs)
        • used the chcon command to set xattrs on memory file systems.
5) It’s Difficult to Apply SELinux Policy to Dalvik Processes 
    – Dalvik limits SELinux’s applicability 
        • altering the zygote code

Steps in Porting SELinux to Android 
– 1. compile kernel with selinux support
– 2. design an Android-specific security policy
– 3.Modify the init process code and init.rc script to support additional commands to load the policy at system startup and set initial labels. 
– 4. Build a new disk image containing the updated init and policy files and updated it on the 
device.

The evaluation tools
– bonnie++
• file system and disk performance benchmark
– Lmbench
• a set of microbenchmarks for low-level Linux functionalities 

Benchmarking
I/O bandwidth、latency、CPU consumption、memory footprint.


将LMbench移植到Android上
http://blog.csdn.net/yiyaaixuexi/article/details/8664957

SELinux Policy Editor
http://seedit.sourceforge.net/