Earth Guardian

You are not LATE!You are not EARLY!

0%

seAndroid 安全机制

seAndroid 安全机制简介。

基本概念

主体/客体

在一个操作系统中,每一个实体组件都必须是主体或者客体,或者既是主体又是客体。

  • 主体
    主体是一个主动的实体,包括用户、用户组、进程等;通常指用户或由用户发起运行的进程或用户正在使用的设备。主体主动发起对资源的访问,它是系统中信息流的启动者。
  • 客体
    客体是一个被动的实体,包括文件、目录、端口、设备、进程等资源;通常是指信息的载体或从其他主体或客体接收信息的实体。主体有时也会成为访问或受控的对象,如一个主体可以向另一个主体授权,一个进程可能控制几个子进程等等,这时受控的主体或子进程也通常被认为是一种客体。

访问控制模式

  • DAC: Discretionary Access Control 自主访问控制
    DAC 主要的内容是:权限 rwx 、所有权 ugo ;在这个模型中,主体是用户的身份,客体是资源或者说是文件( Linux 中一切皆文件)。由客体的属主对自己的客体进行管理,由主体自己决定是否将自己的客体访问权限或部分访问权限授予其他主体,这种控制方式是自主的。也就是说,在自主访问控制下,用户可以按自己的意愿,有选择地与其他用户共享他的文件。
    DAC 是一种相对比较宽松但是却很有效的保护资源不被非法访问和使用的手段,权限是访问的关键;但 Linux 中,root 用户不受任何管制,系统上任何资源都可以无限制地访问。
  • MAC: Mandatory Access Control 强制访问控制
    MAC 是利用策略将访问控制规则“强加”给访问主体的,即系统强制主体服从访问控制策略。MAC 主要作用的对象是所有主体及其所操作的客体(如:进程、文件等)。MAC 为这些主体及其所操作的客体提供安全标记,这些标记是实施强制访问控制的依据。
    系统通过比较主体和客体的安全标记来判断一个主体是否能够访问其要操作的客体。用户发起的进程无法改变其自身及其它客体的安全标记,利用这样的机制,系统可以比较有效地防止特洛伊木马攻击以及 root 身份冒用或盗用等安全威胁。
    MAC 又细分为了两种方式:类别安全 MCS 模式;多级安全 MLS 模式。

MAC 一般与 DAC 共同使用,两种访问控制机制的过滤结果将累积,以此来达到更佳的访问控制效果。也就是说,一个主体只有通过了 DAC 限制检查与 MAC 限制检查的双重过滤装置之后,才能真正访问某个客体。

SELinux 的工作模式

SELinux: Secure Enhanced Linux 是美国国家安全局 NSA: The National Security AgencySCC:Secure Computing CorporationLinux 社区的帮助下开发了 MAC 强制访问控制的安全模块,Linux 从 2.6 版本后将它集成到了内核中。
主体在访问客体时,SELinux 策略决策过程如下图,Kernel 中的策略执行服务器将检查 AVC: Access Vector Cache ,访问矢量缓存中存储的是访问控制策略:

0111-android-seandroid-selinux-policy.png

SELinux 有三种工作模式:

  • enforcing
    强制模式,违反 SELinux 规则的行为将被阻止(权限拒绝)并记录到日志中。
  • permissive
    宽容模式,违反 SELinux 规则的行为(权限不会被拒绝)只会记录到日志中,一般为调试用。
  • disabled
    关闭 SELinux

SEAndroid 是在 Android 系统中基于 SELinux 推出的强制访问控制模型,是 SELinux 的一个子集;可以通过 adb 命令来查看/设置模式:

1
2
3
adb shell getenforce        // 查看当前模式
adb shell setenforce 1 // 设置为 enforcing 模式
adb shell setenforce 0 // 设置为 permissive 模式

CTS 兼容性测试时,Android 有以下要求官方要求

  • 必须实现 SELinux
  • 必须将 SELinux 设置为全局强制模式 enforcing
  • 必须将所有域配置为强制模式。不允许使用宽容模式域,包括特定于设备/供应商的域

访问控制策略 policy

访问控制策略 policy 都是在 .te: Type Enforcement 文件中定义的,用来控制主体是否能访问客体,以及能放问客体哪些东西;下面先介绍几个用来描述主客体的几个概念。更多规则和关键字等基本概念,参考The SELinux Notebook, 4th Edition(SELinux 手册第 4 版)

classes

定义客体的安全类别,可以在 system/sepolicy/private/security_classes 查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Classes marked as userspace are classes
# for userspace object managers

class security
class process
class system
class capability

# file-related classes
class filesystem
class file // 文件
class dir // 目录
class fd // 文件描述符
class lnk_file
class chr_file
class blk_file
class sock_file
class fifo_file

# network-related classes
class socket
class tcp_socket
class udp_socket
...
class binder # Android 平台特有的 binder
...

permissiones

定义每个客体类别支持哪些操作权限,可以在 system/sepolicy/private/access_vectors 中查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Define common prefixes for access vectors
# common common_name { permission_name ... }

# Define a common prefix for file access vectors.
common file // 定义 file 通用的操作权限
{
ioctl
read
write
create
getattr
...
}

# Define a common prefix for socket access vectors.

common socket // 定义 socket 通用的操作权限
{
# inherited from file
ioctl
read
write
...
# socket-specific
bind
connect
listen
accept
...
}
...

class file // 客体类别 file 支持的操作权限
inherits file
{
execute_no_trans
entrypoint
execmod
open
audit_access
}

class dir
inherits file
{
add_name
remove_name
...
}

class socket
inherits socket

class tcp_socket // 客体类别 tcp_socket 支持的操作权限
inherits socket
{
node_bind
name_connect
}
...

attribute 属性

attribute 实际是的概念,表示一组 group ;有了组的概念后,可以每次对一个组设置策略。
attribute 可以是主体,也可以是客体;在 system/sepolicy/public/attributes 文件查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# All types used for processes.
attribute domain;

# All types used for filesystems.
# On change, update CHECK_FC_ASSERT_ATTRS
# definition in tools/checkfc.c.
attribute fs_type;

# All types used for context= mounts.
attribute contextmount_type;

# All types used for files that can exist on a labeled fs.
# Do not use for pseudo file types.
# On change, update CHECK_FC_ASSERT_ATTRS
# definition in tools/checkfc.c.
attribute file_type;

# All types used for domain entry points.
attribute exec_type;

从注释中也可以看出,是 All types 所有的类型,接下来看 type

type

表示类型,可以理解为主体或客体的名称,表示这一类主体或这一类客体;所有的 type 都是在 .te 文件中定义的,同时会设置对应的策略。

  • type 直接定义
    命名格式:type type_id [alias alias_id,] [attribute_id][] 是可选项,alias 表示假名,attribute_id 可以是多个,表示属于哪一组。
    示例:type shell, domain; ;定义了一个名为 shelltype ,它和名为 domain 的属性 attribute 关联;换句话说 shell 属于 domain 组。typeattribute 位于同一个命名空间,所以不能用 type 命令和 attribute 命令定义相同名字的东西。
  • typeattribute 添加对应属性
    typeattribute 是针对已经被定义了的 type ,添加属性(即属于哪一组),格式:typeattribute type_id attribute_id 。示例 typeattribute mediaserver halclientdomain; ,表示 mediaserver 拥有 halclientdomain 属性,即属于这一组。

policy

策略规则 policy 也是在 .te 文件中声明的,其语法格式为:
RULE_VARIANT SOURCE_TYPES TARGET_TYPES:CLASSES PERMISSIONS ,其中:

  • RULE_VARIANT
    常见的访问规则如下,这里仅仅 allow 是授予权限允许操作,其他都是辅助型的(都不会授予权限)。
    • allow 授予权限,允许操作(默认情况下只记录权限检查失败的信息)
    • neverallow 不允许操作(通常用来做检查,检查是否有违反规则)
    • auditallow 记录所有的(成功和失败)权限检查事件
    • dontaudit 不记录权限检查失败的信息
  • SOURCE_TYPES
    主体类型,由 type 定义。
  • TARGET_TYPES
    客体类型,由 type 定义。
  • CLASSES
    客体的安全类别,即 system/sepolicy/private/security_classes 文件中,关键字 class 定义的类别。
  • PERMISSIONS
    客体安全类别的操作权限,即 system/sepolicy/private/access_vectors 文件中,该安全类别对应的操作权限。

policy 描述的含义实际就是:主体对客体的某种类别拥有的权限;示例:

  • allow appdomain app_data_file:file rw_file_perms;
    主体 appdomain 对客体 app_data_filefile 类别,拥有读取和写入权限。其中 rw_file_perms 是宏定义的一组权限。
  • allow domain null_device:chr_file { open read};
    主体 domain 对客体 null_devicechr_file 类别,拥有打开和读的权限。

self 关键字

self 表示客体类型使用的主体类型自身,即客体类型等于主体类型;注意:不能使用 self 代表主体类型。示例:

1
2
3
4
5
6
7
8
9
10
# 这两条策略是相等的 
allow user_t user_t : process signal;
allow user_t self : process signal;

# 这两条策略
allow user_t user_t : process signal;
allow staff_t staff_t : process signal;

# 等于下面这一条策略
allow {user_t staff_t} self : process signal;

特殊操作符

  • - 非操作符
    表示从 attribute 一组类型中,移除特定类型;如: allow vndservicemanager { domain -coredomain -init }:binder transfer; ,表示 vndservicemanager 除了 coredomain, init 以外,所有 domainbinder 类别,都拥有 transfer 操作权限。
  • ~ 求补操作符
    表示除了列出的操作权限外,其他的都包含;如 allow init unlabeled:filesystem ~relabelto;
  • * 通配符
    表示任意的;
    neverallow * logpersist:process dyntransition
    neverallow mediacodec domain:{ tcp_socket udp_socket rawip_socket } *;

示例

以下是一个完整的 DHCP 策略示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
type dhcp, domain;
permissive dhcp; // 声明为宽容域
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;

init_daemon_domain(dhcp)
net_domain(dhcp)

allow dhcp self:capability { setgid setuid net_admin net_raw
net_bind_service};
allow dhcp self:packet_socket create_socket_perms;
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write };
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
# For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net:file write;
allow dhcp system_prop:property_service set ;
unix_socket_connect(dhcp, property, init)

type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;

allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{dgram_socket_class_set unix_stream_socket} {read write};
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };
  • type dhcp, domain;
    定义一个 dhcp 域,它属于 domain 组。
  • permissive dhcp;
    声明新建的 dhcp 域为宽容域(调试完毕后,必须要移除)。
  • type dhcp_exec, exec_type, file_type;
    定义 dhcp_exec ,同时属于 exec_type, file_type 组。
  • init_daemon_domain(dhcp)
    声明 dhcp 是从 init 衍生而来的,并且可以与其通信。init_daemon_domain 等域操作,详细可以参考 system/sepolicy/public/te_macros 中的定义。
  • allow dhcp self:packet_socket create_socket_perms;
    允许 dhcp 创建 socket ,权限类 create_socket_perms 等参考 system/sepolicy/public/global_macros 中的定义。

目录速查表

selinux 代码目录

位于 Android 源码目录的 external/selinux 目录下,external/selinux/prebuilts/bin 有些工具类文件,方便快速分析权限问题。

policy 文件目录

Android 8.0 及更高版本中,policy 文件位于 AOSP 中的以下位置:

  • system/sepolicy/public
    其中包括所导出的用于供应商特定策略的策略;公共策略会保留在不同版本上,可以在自定义策略的 /public 中添加任何内容。正因如此,可存放在 /public 中的策略类型的限制性更强。将此目录视为相应平台的已导出策略 API:处理 /system/vendor 之间的接口的所有内容都位于这里。
  • system/sepolicy/private
    包括系统映像正常运行所必需(但供应商映像策略应该不知道)的策略。
  • system/sepolicy/vendor
    包括位于 /vendor 但存在于核心平台树(非设备特定目录)中的组件的相关策略。这是编译系统区分设备和全局组件的软件工件;从概念上讲,这是下述设备专用策略的一部分。
  • device/manufacturer/sepolicy/device-name
    包含设备专用策略,以及对策略进行的设备自定义(在 Android 8.0 及更高版本中,该策略对应于供应商映像组件的相关策略)。

通常情况下,不能直接修改 system/sepolicy 文件,而是添加或修改自己的设备专用策略文件(位于 /device/manufacturer/device-name/sepolicy 目录中)。

宏定义

系统的策略文件中,定义很多宏,方便共享和快速定义策略文件,路径如下:

1
2
3
4
5
6
system/sepolicy/public/ioctl_macros         // ioctl
system/sepolicy/public/global_macros // 权限
system/sepolicy/public/te_macros // 域操作
system/sepolicy/public/neverallow_macros
system/sepolicy/reqd_mask/mls_macros
system/sepolicy/private/mls_macros

标签

定义

标签,也被称为安全上下文 security context ,组成元素为:user:role:type:mls_level ,每个元素的意义:

  • user
    指登录系统的用户类型,比如 root, user_u, system_u ;但是在 SEAndroiduser 只有一个,都是 u
  • role
    定义文件、进程和用户的用途。在 SEAndroid 中的 role 只有两个:object_r 表示文件;r 表示进程。
  • type
    指定主体和客体的类型。
  • mls_level
    指安全级别,格式为 sensitivity[:category list][- sensitivity[:category list]],冒号后面的内容是 category ,“-”号左右分别标识了安全级别的最低和最高;例如 s0 - s15:c0.c1023 ,其中 s0 之后的内容可以不需要。
    SEAndroid 中只有一个级别即 s0category 共有 1024 个,因此最低安全级别就是 s0,最高安全级别就是 s0:c0.c1023 ,通常我们就只会看到 s0

SEAndroid 中,标签的角色仅仅只有两个:进程和文件。进程标签的 type 又称为;所以 policy 也可以理解为 - 进程访问文件权限的规则:allow domains types:classes permissions;
AVC 消息中,主体上下文(标签)为 scontext ;客体上下文(标签) tcontext ,客体类别 tclass

Linux 中一切都是文件,所以我们在打标签时,不可能存在 r 角色;所有的进程在系统中都是一个可执行文件,所以对于进程的标签通常是:先在 te 文件中通过 type 定义一个类型;然后在 file_contexts 中为进程对应的可执行文件打上该 type 标签。

查看标签

我们通过 ls -Zps -AZ 分别查看文件和进程(两个角色)的标签,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 查看文件角色的标签
ELUGA_Ray_710:/ # ls -Z
u:object_r:cgroup:s0 acct
u:object_r:rootfs:s0 bt_firmware
u:object_r:rootfs:s0 bugreports
u:object_r:cache_file:s0 cache
u:object_r:rootfs:s0 charger
u:object_r:configfs:s0 config
u:object_r:rootfs:s0 d
u:object_r:system_data_file:s0 data
u:object_r:rootfs:s0 default.prop

// 查看进程角色的标签
ELUGA_Ray_710:/ # ps -Z
LABEL USER PID PPID VSZ RSS ADDR S NAME

u:r:shell:s0 root 6897 592 9228 1928 772c07a568 S sh
u:r:shell:s0 root 7930 6897 10804 2032 792b23ef10 R ps

type 是整个 SEAndroid 中最重要的参量,所有的 policy 都围绕这一参量展开,所以为系统中每个文件标记上合适的 type 就显得极为重要了。通过 *_contexts 上下文描述文件,来给具体的文件或进程打标签。

file_contexts

用于为文件(分为:进程对应的可执行文件(主体)和常规文件(客体))分配标签,并且可供多种用户空间组件使用。在创建新策略时,请创建或更新该文件,以便为文件分配新标签。要应用新的 file_contexts,请重新构建文件系统映像,或对要重新添加标签的文件运行 restorecon。在升级时,对 file_contexts 所做的更改会在升级过程中自动应用于系统和用户数据分区。此外还可以通过以下方式使这些更改在升级过程中自动应用于其他分区:在以允许读写的方式装载相应分区后,将 restorecon_recursive 调用添加到 init.board.rc 文件中。 file_contexts 所在目录为:

1
2
3
4
5
system/sepolicy/private/file_contexts
system/sepolicy/vendor/file_contexts
device/manufacturer/device-name/sepolicy/file_contexts
device/manufacturer/sepolicy/device-name/file_contexts
device/manufacturer/sepolicy/private/file_contexts

查询 private/file_contexts 文件中的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// system/sepolicy/private/file_contexts
# Root
/ u:object_r:rootfs:s0

# Data files
/adb_keys u:object_r:adb_keys_file:s0
/build\.prop u:object_r:rootfs:s0
...
/verity_key u:object_r:rootfs:s0

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

# For kernel modules
/lib(/.*)? u:object_r:rootfs:s0

# Empty directories
/lost\+found u:object_r:rootfs:s0
/mnt u:object_r:tmpfs:s0
...

# Symlinks
/bugreports u:object_r:rootfs:s0
...

file_contexts 中的 type 类型,基本都是在如下 .te 文件中定义的:

1
2
3
4
5
6
7
8
9
10
11
12
13
// file.te
system/sepolicy/private/file.te
system/sepolicy/vendor/file.te
system/sepolicy/public/file.te
device/manufacturer/sepolicy/device-name/file.te
device/manufacturer/sepolicy/private/file.te
device/manufacturer/sepolicy/public/file.te

// device.te
system/sepolicy/public/device.te
device/manufacturer/sepolicy/private/device.te
device/manufacturer/sepolicy/public/device.te
device/manufacturer/sepolicy/device-name/device.te

查询 system/sepolicy/public/file.te 文件中的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Filesystem types
type labeledfs, fs_type;
type pipefs, fs_type;
type sockfs, fs_type;
type rootfs, fs_type;
type proc, fs_type;
# Security-sensitive proc nodes that should not be writable to most.
type proc_security, fs_type;
type proc_drop_caches, fs_type;
type proc_overcommit_memory, fs_type;
# proc, sysfs, or other nodes that permit
# configuration of kernel usermodehelpers.
type usermodehelper, fs_type;
type sysfs_usermodehelper, fs_type, sysfs_type;
type qtaguid_proc, fs_type, mlstrustedobject;
type proc_bluetooth_writable, fs_type;
...

service_contexts

用于为 Android Binder 服务分配标签,以便控制哪些进程可以为相应服务添加(注册)和查找(查询) Binder 引用,在启动期间 servicemanager 进程会读取此配置。service_contexts 所在目录:

1
2
3
4
system/sepolicy/private/service_contexts
device/manufacturer/sepolicy/device-name/service_contexts
device/manufacturer/sepolicy/private/service_contexts
device/manufacturer/sepolicy/common/service_contexts

查看 system/sepolicy/private/service_contexts 中的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
launcherapps u:object_r:launcherapps_service:s0
location u:object_r:location_service:s0
lock_settings u:object_r:lock_settings_service:s0
...
media.camera u:object_r:cameraserver_service:s0
media.camera.proxy u:object_r:cameraproxy_service:s0
media.log u:object_r:audioserver_service:s0
...
netd u:object_r:netd_service:s0
netpolicy u:object_r:netpolicy_service:s0
netstats u:object_r:netstats_service:s0
...

service_contexts 中的 type 类型,基本都是在 service.te 文件中定义的:

1
2
3
4
system/sepolicy/public/service.te
device/manufacturer/sepolicy/device-name/service.te
device/manufacturer/sepolicy/private/service.te
device/manufacturer/sepolicy/common/service.te

查看 system/sepolicy/public/service.te 中的示例:

1
2
3
4
5
6
7
8
type audioserver_service,       service_manager_type;
...
type cameraserver_service, service_manager_type;
type default_android_service, service_manager_type;
type drmserver_service, service_manager_type;
type dumpstate_service, service_manager_type;
type fingerprintd_service, service_manager_type;
...

其他上下文标签

  • genfs_contexts
    用于为不支持扩展属性的文件系统(例如 proc, vfat )分配标签。此配置会作为内核策略的一部分进行加载,但更改可能对内核 inode 无效。要全面应用更改,需要重新启动设备,或卸载并重新装载文件系统。此外通过使用 context=mount 选项,可以为装载的特定系统文件(例如 vfat )分配特定标签。
  • property_contexts
    用于为 Android 系统属性分配标签,以便控制哪些进程可以设置这些属性。在启动期间 init 进程会读取此配置。
  • seapp_contexts
    用于为应用进程和 /data/data 目录分配标签。在每次应用启动时,zygote 进程都会读取此配置;在启动期间 installd 会读取此配置。
  • mac_permissions.xml
    用于根据应用签名和应用软件包名称(后者可选)为应用分配 seinfo 标记。随后分配的 seinfo 标记可在 seapp_contexts 文件中用作密钥,以便为带有该 seinfo 标记的所有应用分配特定标签。在启动期间 system_server 会读取此配置。

添加/修改策略 policy

原则

  • 采用最小权限原则,仅针对添加的内容调整 SELinux 策略
  • 将各个软件组件拆分成多个负责执行单项任务的模块,创建将这些任务与无关功能隔离开来的 SELinux 策略
  • 将这些策略放在 /device/manufacturer/sepolicy/device-name 目录中的 *.te 文件,然后使用 BOARD_SEPOLICY 变量将它们纳入到版本中
  • 先将新域设为宽容域:在该域的 .te 文件中使用宽容声明 permissive *** ;分析结果并优化域定义,当版本中不再出现拒绝事件时,移除宽容声明

编译

策略修改和添加,尽量都放在 /device/manufacturer/sepolicy/device-name 目录中实现,方便后续追溯。同时需要在 /device/manufacturer/device-name/BoardConfig.mk 中指定 sepolicy 子目录和每个新的策略文件。详细请参阅 system/sepolicy/README 文件。

1
2
3
4
5
6
7
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te

重新进行编译后,新策略设置会自动内置到最终的内核策略文件中。

示例

以下为 Android 官网上提供的示例:
为新服务添加标签并解决拒绝事件,通过 init 启动的服务需要在各自的 SELinux 域中运行。以下示例会将服务 foo 放入它自己的 SELinux 域中并为其授予权限。

该服务是在设备的 init.device.rc 文件中启动的,如下所示:

1
2
3
// 服务进程对应的可执行文件
service foo /system/bin/foo
class core
  • 创建一个新域 foo
    创建包含以下内容的文件 device/manufacturer/sepolicy/device-name/foo.te
    1
    2
    3
    4
    5
    6
    # 为进程定义一个类型
    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;

    init_daemon_domain(foo)
    这是 foo SELinux 域的初始模板,可以根据该可执行文件执行的具体操作为该模板添加规则。
  • /system/bin/foo 添加标签
    将以下内容添加到 device/manufacturer/sepolicy/device-name/file_contexts
    1
    2
    3
    # 为进程对应可执行文件打标签,类型对应的是给进程分配的类型
    # file_contexts
    /system/bin/foo u:object_r:foo_exec:s0
    这可确保为该可执行文件添加适当的标签,以便 SELinux 在适当的域中运行相应服务。
  • 编译并刷写启动映像和系统映像
  • 优化相应域的 SELinux 规则
    根据拒绝事件确定所需的权限。audit2allow 工具提供了一些实用的指南,但该工具仅适用于提供编写政策时所需的信息。切勿只是复制输出内容。

audit 日志分析

SELinux 有大量的工具记录日志信息,或审核、访问尝试被策略允许或拒绝的信息。审核消息通常叫做 AVC 消息,它提供了详细了关于访问尝试的信息,包括是允许还是拒绝,源和目标的安全上下文,以及其它一些访问尝试涉及到资源信息。
avc dennied 的示例 log :

1
2
3
// a.txt
avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0” dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

可以通过 external/selinux/prebuilts/bin/audit2allow 提供的工具来分析:

1
2
3
4
xmt@server139:~/external/selinux/prebuilts/bin$ audit2allow -i a.txt

#============= mediaserver ==============
allow mediaserver device:chr_file { read write };

工具自动生成,通常给的权限范围会过大,需要手动细化,满足最小权限原则。

后续

  • 域转换
  • 角色转换
  • 实例分析

参考文档