您的位置:首页 > 移动开发 > Android开发

SE for Android 系列之整体概要

2015-08-05 18:12 435 查看
引言

由于目前关于SE for Android的介绍相对比较缺泛,因此本文的主要目的就是对整个SE for Android进行详细的介绍,同时可以作为相关工具、命令行、策略构建工具以为策略文件格式的使用说明书。

术语

先了解一下三个重要的术语,分别是SE for Android、AOSP和SEAndroid。
SE for Android用于描述整套SELinux mandatory accss control(MAC)以及Middle-ware mandatory access control(MMAC)在Android上的实现。
AOSPAOSP即是指Android的源码版本,其下载地址为Google分布(http://source.android.com/source/downloading.html),其中从Release
4.3开始,AOSP源码已经包含SELinux的支持,相关的说明见http://source.android.com/devices/tech/security/se-linux.html

AOSP中包含SELinux MAC的核心功能以及一些简单的策略,系统上所有的进程domains都是unconfined的状态。而且Install MMAC框架和策略也没有添加过多的限制,详情可以查看“所支持的MAC服务”一节的内容。

AOSP的原则是所有的第三方应用都是平等对待,这意味着第三方的应用不能运行在不同的domains中,也无法为其单独配置MAC/MMAC策略。AOSP只对系统应用进行策略限制。
SEAndroidSEAndroid就是指在AOSP发行版本的基础上添加了一系列功能之后的版本(相当于是SELinux的功能加强版),这些功能如下所列:

a) 安全加强的MAC策略,以保证所有进程的domain都是被定义,同时SELinux的默认模式是enfocing;

b) 安全加强的MMAC策略;

c) 增加了Intent MMAC的支持;

d) 增加了Content Provider MMAC的支持;

e) 增加了Revoke permissioin(权限吊销) MMAC的支持;

这些功能的详细描述,见“所支持MAC服务”一节
SE for Android的项目编译

一共有5种不同的SE for Android的项目构建方式,分别是:

1) 标准的AOSP版本(从4.3版开始),这个版本不需要额外的代码补充,其他四种方式都需要从 https://bitbucket.org/seandroid/manifests获取额外的代码;

2) git checkout master——包含安全加强的SELinux MAC + 安全加强的Intall MMAC;

3) git checkout intent_mac——包含安全加强的SELinux MAC + 安全加强的Intall MMAC + Intent MMAC;

4) git checkout cp_mac ——包含安全加强的SELinux MAC + 安全加强的Intall MMAC + Intent MMAC + Content Provider MMAC;

5) git checkout revoke-perms——包含安全加强的SELinux MAC + 安全加强的Intall MMAC + Revoke permissions策略;

Android源码的git地址是https://android.googlesource.com,SEAndroid enhancements的git地址是https://bibucket.org/seandroid.

有用的链接

关于如何实现和测试集成了SELinux功能的AOSP发行版本:http://source.android.com/devices/tech/security/se-linux.html

关于目前SEforAndroid与跟AOSP的合并情况、如何获取代码、如何安装、有哪些功能: http://selinuxproject.org/page/SEforAndroid

Security Enhanced (SE) Android: Bringing Flexible MAC to Android : http://www.internetsociety.org/sites/default/files/02_4.pdf (强烈推荐阅读)

关于三星的"KNOX"的详细介绍:http://www.samsung.com/global/business/business-images/resource/white-paper/2013/05/Samsung_KNOX_whitepaper_April2013_v1.1-0.pdf

接下来的章节将包含下列内容

MAC和Middleware MAC的介绍
为了支持MAC功能,Android源码上的变化
增加kernel LSM/SELinux的支持
与SE for Android功能相关的Classes & Permissions
为支持SE for Android所增加的SELinux命令和方法
init为支持SELinux的扩展
策略构建和编译

编译文件的位置

策略布尔值

策略配置文件

Install / run time MMAC 配置文件

Intent MMAC配置文件

Content Provider MMAC配置文件

Revoke permissions MMAC配置文件

日志和审计
libselinux添加的函数

所支持的MAC服务

MAC和MMAC功能概述:

标准的SELinux MAC 策略是基于type enforcement(TE,即类型强制访问)/ multi-level security (MLS,即多级别安全机制),也可以理解为是一种白名单机制;
Install MMAC策略中的package和signature标签支持通过setinfo标签,来指定应用的context(安全上下文,指运行时domain)。该策略只对预装应用生效,而第三方的应用则无法通过这种方式指定,所有的第三方应用都只能由<default>标签匹配,而且seinfo的值为“default”。(译者注,这里会让你看得头晕,建议找到mac_permissions.xml文件对着看)

SEAndroid Install MMAC策略还能能够检查应用所申请的权限列表是否被允许。如果不允许,那么该应用就不能够安装。另外如果这款应用已经安装在手机上了,后来策略更新并与其产生冲突了,那么这款应用也不能运行。配置文件允许的动作有:allow(允许),deny(拒绝)和allow all permissions(允许所有权限)。 检查流程如下:

安装或升级第三方应用时,它的权限列表都被会检查。如果在<default>里存在任意一项不被允许的权限,那么该应用安装或升级过程就会失败;
预装的应用,他们的升级过程,系统也会去做一次权限检查。如果在package或者signature标签存在不允许的权限,更升级失败。如果存在某个权限,在package或者signature标签中没有显式声明为allow,而在default标签中声明为deny的话,升级过程同样会失败;

Intent MMAC策略的作用是决定Intent是否能够被分发到其他几种组件。策略会屏蔽掉所有没有被定义为允许的Intent分发。这是一个可选的策略,并不需要定制的SELinux策略支持,不过它可以对“主体”的安全上下文进行合法性校验。
Content Provider MMAC策略作用是决定content provider的访问请求是否被允许。策略会屏蔽掉所有没有被定义为允许的访问请求。目前的版本支持use, read, read/write三种权限。这是一个可选的策略,并不需要定制的SELinux策略支持。
Revoke permissions策略的作用是决定权限在运行过程中是否会被检查,如果权限被撤消了那么权限就会变成denied状态(也就是说,除了指定的权限会被变成denied,其他的权限都是允许的)。这是一个可选的策略,并不需要定制的SELinux策略支持。

Android为支持MAC所引入的变化

SE for Android为Android的内核增加了SELinux的支持,同时在用户空间也实现了如下几方面的目标:

定义所有具有特权守护进程,以防止权限被滥用以及把它们的破坏降到最低;
构造沙箱,使应用与应用和系统之间互相隔离;
防止应用提权;
利用MMAC策略,使应用的权限在安装和运行的过程中变得可控;
提供一种集中的、可分析的策略;

这些目标是由下列改措实现的:

实现了yaffs2文件系统的安全标注;
文件系统镜像文件(yaffs2和ext4)编译时标注;
为recovery console和程序更新器提供标注功能;
基于内核的Binder IPC权限检测;
实现对由init进程所产生的服务端套接字(service sockets)和本地套接字文件(socket files)的标注功能;
实现对由ueventd进程所产生的设备节点(device nodes)的标注功能;
为应用和应用数据文件夹提供灵活易配置的标注功能;
最小化SELinux用户空间的可用端口;
提供了JNI方式的SELinux接口;
为Zygote socket commands的使用提供了用户空间级别的权限检查;
为Android properties的使用提供了用户空间级别的权限检查;
专门针对Android编写了TE策略文件;
为所有系统服务和应用定义domain;
利用MLS类别隔离应用;

SE 对Android项目的变动

external/libselinux

提供了SELinux用户空间的函数库并集成到设备上。该库在原版本的基本上为适应Android而增加了一列的函数,如下所示:

selinux_android_setcontext

利用这个函数可以为应用设置正确的domain上下文,它会利用保存在seapp_contexts文件里的信息计算出正确的上下文。如果是在初始化阶段,这个函数也会调用selinux_android_seapp_context_reload加载seapp_contexts文件并对里面的每一项进行排序,详细过程见"seapp_contexts文件"一节。

该函数会被dalvik/vm/native/dalvik-system-Zygote.cpp和system/core/run-as/run-as.c调用。

selinux_android_setfilecon2

利用这个函数可以为应用文件夹和文件设置正常的上下文,它会利用保存在seapp_contexts文件里的信息计算出正确的上下文。如果是在初始化阶段,这个函数也会调用selinux_android_seapp_context_reload加载seapp_contexts文件并对里面的每一项进行排序,详细过程见"seapp_contexts文件"一节。
当安装应用时,该函数会被frameworks/base/cmds/installd/commands.c调用。

selinux_android_restorecon

利用这个函数可以让文件的上下文恢复成file_contexts文件里初始配置。该函数在初始经和安装等过程过程中会被多处调用。

selinux_android_load_policy

如果SELinux是开启的话,利用该函数可以加载SELinux文件系统,并通过调用selinux_android_reload_policy把策略文件加载到内核。

selinux_android_reload_policy

加载策略文件进内核。该函数会被system/core/init.c调用。

external/libsepol

提供了用户空间的策略工具库。这部分代码跟SELinux是一样的,而且不会集成到设备上。

external/checkpolicy

提供了策略构造工具。这部分代码跟SELinux是一样的,而且也不会集成到设备上(因此策略的构造必须在主机开发环境中进行)。

external/sepolicy

这个SE for Android特有的部分,里面包含各种策略模块(*.te文件),class/permissoin文件等等。所有策略模块依据Android.mk文件进行构造的,最终会连同其他配置文件(file_contexts, seapp_contexts和property_contexts)一起集成到设备上(编译成sepolicy文件)。也有一些工具可以根据不同的设备进行策略补充,这部分会在“策略构建”一节详细描述。
策略文件的在“SELinux MAC配置文件”一节进行详细描述。相关的工具也会在“策略构建工具”一节有详细的描述。
这里也包含了关于SE for Android的类定义,详细可以查看“SE for Android 的类和权限”一节。
这个文件夹也包含了Install MMAC、Intent MMAC、Content Permission MMAC策略,如果有配置的话,请参考“SE for Android 系列之整体概要(一)”中的“SE
for Android的项目编译”一节。

external/mac-policy

这里包含revoke permission的策略配置文件(revoke_permission.xml),利用这种策略可以让Android的权限动态撤消。 如果项目选项选择revoke_perms的话,就会包含这个文件夹。

build

针对SE for Android进行修改。

dalvik

当进程被fork后,会使用selinux_android_setcontext进行domain上下文设置。

libcore

Zygote.java里添加了setInfo和niceName两种传入参数(译者注,应该是zygote command命令里添加了--setInfo和--niceName两种配置)

frameworks/base

JNI——添加了SELlinux的函数支持,如isSELinuxEnabled和setFSCreateCon。
SELinux 的Java类和方法的定义。
Zygote连接者的安全上下文检查。
为package manager和各种service提供文件权限的管理(译者注,这里不太明白)
添加MMAC框架

system/core

支持SELinux的toolbox,比如load_policy, runcon
支持SELinux的系统初始化,比如init,init.rc
支持SELinux的核审服务(audittd)

system/extras

支持SELinux的ext4文件系统

kernel

已经有多个内核增加了LSM和SELinux支持,详细可以查看SEforAndroid
- Building for a Device.
Android的内核存在多个版本(目前是3.4,模拟器使用的是Goldfish),因此最新版本的SELinux一般还没有集成到SEforAndroid。在“内核LSM和SELinux的支持”一节里,会详细说明内核的变化。

device

关于支持设备的详情情况,可以查看SEforAndroid
- Building for a Device

可以修改设备的配置文件定制策略文件,详细见“构建策略文件”一节

内核LSM和SELinux的支持

文章 Security
Enhanced (SE) Android: Bringing Flexible MAC to Android对内核的修改情况做了很好的描述,下面主要讲一下为支持Binder IPC服务所作的变化:

Linux安全模块(LSM)在binder驱动代码(drivers/staging/android/binder.c和include/linux/security.h)添加了钩子逻辑;
在没有其他模块的情况下,默认支持能力("capabilities")(security/capability.c);
LSM安全模块添加了钩子逻辑;
对显示在“SE for Android的类别和权限”一节中所列的客体类别和权限提供支持(security/selinux/include/classmap.h);

SE for Android的客体类别和权限

SE for Android添加了三个客体类别(binder, zygote和property_service),下表描述它们权限:

binder 类别 - 这是管理内核Binder IPC服务的客体类别
权限描述
call通过IPC方式访问一个指定的进程(A能否访问B?)。
impersonate接管IPC通讯(A能否接管B的IPC通讯?)。

目前策略还没有使用,但selinux_binder_transaction调用时内核有做检查。
set_context_mgr把自身注册成Binder Context Manager。如果A能为把B设置为context manager,就意味着A==B。参考策略文件servicemanager.te
transfer传递binder引用给其他进程 (A能否把binder引用传递给B?)。
zygote 类别 – 这是用户空间的客体类别,管理Android应用的装载。参考SELinux.checkSELinuxAccess.
In ZygoteConnection.java
权限描述
specifyids指定应用的uid或者gid
specifyrlimits指定应用的资源限制
specifycapabilities指定应用的capabilities
specifyinvokewith指定应用要使用--invoke-with启动Zygote,这是一种包装命令的使用方式
specifyseinfo指定seinfo标签决定应用的安全上下文
property_service 类别 – 这是用户空间的类别,用于管理Android Property Service
权限描述
set设置一个属性
SELinux命令行
SE for Android为Android了一个SELinux命令的子集,见表1。他们作用于Toolbox命令,也可以通过adb shell命令调用,比如:
adb shell su to setenforce permissive

表1:开启SELinux的adb shell命令(在Android toolbox里)

命令注释
chcon修改文件的安全上下文. 只支持第一部分的chcon(1)功能 (目前仅支持context pathname的格式).
chcon context pathname

getenforce获取当前的工作模式
getenforce

getseboolGet SELinux boolean value(s):
getsebool [-a | boolean]

id不带任意选项,如果开启了SELinux,那么安全上下文的信息就会自动显示
load_policy把新策略加载入内核
load_policy policy-file

ls支持通过-Z选项显示安全上下文信息
restorecon按file_contexts文件的策略恢复文件的安全上下文。与restorecon(8)相比,有部分选项不支持

restorecon [-nrRv] pathname

runcon以指定的安全上下文件运行命令

runcon context program args...

setenforce修改SELinux的工作模式

setenforce [enforcing|permissive|1|0]

setsebool修改SELinux布尔值(需要注意,这种修改重启后失效)

setsebool name [1|true|on|0|false|off]


SELinux 的公开方法
这些公开方法等价于在liselinux里的方法,见表2。源码在framework/base/java/andoid/os/SElinux.java。

表2:SELinux公开的类和方法

boolean isSELinuxEnabled()
获取SELinux开启状态

如果上开启状态,则返回true

boolean isSELinuxEnforced()
判断SELinux是否处于permissive或enforcing模式

如果是enforcing模式,则返回true

boolean setSELinuxEnforce(boolean value)
设置SELinux的工作模式(permissive或者enforcing)

value为true表示enforcing模式

设置成功返回true

boolean setFSCreateContext(String context)
设置新建文件对象的安全上下文

context为被指定安全上下文

设置成功返回true

boolean setFileContext(String path, String context)
修改现有文件的安全上下文

path是被修改的文件路径

context为被指定的安全上下文

设置成功返回true

String getFileContext(String path)
获取文件的安全上下文

path 文件路径.

返回文件的安全上下文件字符串或者null

String getPeerContext(FileDescriptor fd)
获取本地socket的安全上下文

FileDescriptor是socket所绑定的文件

返回socket上下文件字符串或者null

String getContext()
获取当前进程的安全上下文

返回当前进程的安全上下文或者null

String getPidContext(int pid)
获取指定pid的进程安全上下文

pid 进程pid

返回进程的安全上下文或者null

String[] getBooleanNames()
获取SELinux的布尔值键名列表

返回包含所有SELinux布尔值键名的字符串数组

boolean getBooleanValue(String name)
获取指定键名的布尔值

name 键名.

返回true或false

boolean setBooleanValue(String name, boolean value)
根据键名设置布尔值。需要注意,重启后会失效。

name 键名

value 重的布尔值

操作成功返回true

boolean checkSELinuxAccess(String scon, String tcon, String
tclass, String perm)

判断两个安全上下文之间指定的权限是否被允许

scon 源或宾体安全上下文

tcon 目标或客体安全上下文

tclass 客体类别名称

perm 权限名称

权限允许则返回true

boolean restorecon(String pathname)
恢复文件为默认的安全上下文。如果系统没有包含SElinux或者处于关闭状态,都会自动返回true

pathname 文件路径

操作成功则返回true

如果pathname为null会抛NullPointerException异常

boolean restorecon(File file)
恢复文件为默认的安全上下文。如果系统没有包含SElinux或者处于关闭状态,都会自动返回true

file 文件对象.

操作成功则返回true

如果file为null会抛NullPointerException异常


Android init语言对SELinux的扩展
Android的init进程语言已经被扩展成为能够支持SELinux,见表3。完整的Android init语言描述见system/core/init/readme.txt文件

表3:SELinux init 扩展

seclabel <securitycontext>

在服务在运行之前修改其安全上下文,主要用在位于rootfs分区的服务,比如ueventd, adbd。而位于system分区的服务,则可以通过transitions规则进行修改,如果没有指定transition规则,那么默认就是init context
restorecon <path>



根据file_contexts的配置恢复指定路径的文件安全上下文.
setcon <securitycontext>



设置当前进程的安全上下文。这一般用在early-init里设置init进程的安全上下文用的(见下面使用示例)。
setenforce 0|1

设置SELinux工作模式. 0 代表 permissive , 1 代表 enforcing。
setsebool <name> <value>

设置SELinux的布尔值

<value> 可以是 1|true|on 或者 0|false|off
使用示例见下面init文件的片断:
# system/core/rootdir/init.rc

...
on early-init
    # Set init and its forked children's oom_adj.
write /proc/1/oom_adj -16

    # Set the security context for the init process.
    # This should occur before anything else (e.g. ueventd) is started.
setcon u:r:init:s0
start ueventd
...
on boot
...
service ueventd /sbin/ueventd
    class core
    critical
    seclabel u:r:ueventd:s0

# device/generic/goldfish/init.goldfish.rc

...
on boot
    setsebool in_qemu 1
    restorecon /sys/qemu_trace/process_name
    restorecon /sys/qemu_trace/state
    restorecon /sys/qemu_trace/symbol
...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: