Android安全策略Selinux小结

Android安全策略Selinux小结_第1张图片

在 Android 4.3版本之前,Android通过DAC(Discretionary Access Control)自主访问控制来进行权限管理。

DAC 的核心思想很简单,通俗的来讲就是“谁创造了我,我就拥有谁的权利”。比如, root 用户启动 Camera,那么 Camera 就有 root 用户的权限,在 Linux 系统上能干任何事情。

很显然,DAC 管理太过宽松,只要想办法在 Android 系统上获取到 root 权限就可以了。所以在Android5.0版本之前,android系统很容易被破坏,设备厂商也经常在保修单中明确说明“Root不保修”的政策。

那么该如何解决这个问题呢? Google在android4.3版本上便引入了SElinux,只不过是默认关闭的状态,在Android5.0上默认强制打开。

SElinux是一种新的安全模型,这中模型叫 MAC(Mandatory Access Control),翻译为强制访问控制。在Linux系统中,相信大家都听过一句话叫作“一切皆文件”,但是文件可分为两种“活的”和“死的”,“活的”是进程,映射到软件层面的意思是:活的进程能发起动作,例如它能打开文件并操作它,而死的文件只能被进程操作。

SELinux的政策规定进程如果想干事情,都必须在《安全策略文件》中赋予权限,凡是没有出现在安全策略文件中的权限都会被拒绝。

在 SELinux 中,每种东西都会被赋予一个安全属性,官方说法叫做 Security Context,Security Context 是一个字符串,同时也分为进程和文件两种

进程的Security Context:

例如通过 ps -Z | grep sharplogcat 命令查看sharplogcat进程:

lcd_xxgae7a:/ # ps -AZ | grep sharplogcat

u:r:sharplogcat:s0 system 2640 1 9188 3092 __skb_wait_for_more_packets 0 S sharplogcat

其中

- u 为user的意思,SEAndroid 中定义了一个 SELinux 用户,值为 u

- r 为 role 的意思,role 是角色之意,它是 SELinux 中一个比较高层次,更方便的权限管理思路。简单点说,一个 u 可以属于多个 role,不同的 role 具有不同的权限。

- sharplogcat代表该进程所属的 Domain(域) 为 init 。MAC强制访问控制 的基础管理思路其实是 Type Enforcement Access Control(简称TEAC,一般用TE表示),对进程来说,Type 就是 Domain,比如 sharplogcat需要什么权限,都需要通过 allow 语句在 te 文件中进行说明。

- s0 是 SELinux 为了满足军用和教育行业而设计的 Multi-Level Security(MLS)机制有关。简单点说,MLS 将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问

文件的Security Context:

例如通过 ls -AZ vendor/bin/sharplogcat 命令查看sharplogcat文件:

lcd_xxgae7a:/ # ls -AZ vendor/bin/sharplogcat

u:object_r:sharplogcat_exec:s0 vendor/bin/sharplogcat

其中

u:同样是 user 之意,它代表创建这个文件的 SELinux user

object_r:文件是死的东西,它没法扮演角色,所以在 SELinux 中,死的东西都用 object_r 来表示它的 role

sharplogcat_exec,和进程的 Domain 是一个意思,它表示 sharplogcat 文件所属的 Type 是 sharplogcat_exec

s0:MLS 的等级

SELinux 规范

allow domains types:classes permissions;

- Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。

- Type - 一个对象(例如,文件、套接字)或一组对象的标签。

- Class - 要访问的对象(例如,文件、套接字)的类型。

- Permission - 要执行的操作(例如,读取、写入)。

= allow : 允许主体对客体进行操作

= neverallow :拒绝主体对客体进行操作

= dontaudit : 表示不记录某条违反规则的决策信息

= auditallow :记录某项决策信息,通常 SElinux 只记录失败的信息,应用这条规则后会记录成功的决策信息。

实例介绍

以上面介绍的sharplogcat为例:在系统rc文件创建sharplogcat进程(该进程类似于原生的logcat,用于记录android log),默认不自启动,通过程序控制启动

service sharplogcat /vendor/bin/sharplogcat -n 1 -r ${persist.sys.logbuffer} -v time -f ${sys.android.log}

user system

group system

disabled

oneshot

system/sepolicy/目录下是Android系统默认的策略文件,这些文件在编译后会包含 SELinux 内核安全政策,并涵盖上游 Android 操作系统。但我们在配置添加SELinux策略文件时并不是在该目录下,而是在/device/manufacturer/device-name/sepolicy 目录中,如HISI平台的为device/hisilicon/bigfish/external/sepolicy目录下。

1. 配置新的sharplogcat.te政策文件,在编译到单个 SELinux 内核政策文件时,新的政策文件会与现有的政策文件组合在一起,te文件中按照sharplogcat所需要的权限进行配置(切记不可为了方便,把所有的权限加进去,应该是需要哪些加哪些):

# Policy for sharplogcat

type sharplogcat, domain;

type sharplogcat_exec, exec_type, file_type, vendor_file_type;

init_daemon_domain(sharplogcat)

allow sharplogcat sharplogcat:capability { dac_override sys_nice };

allow sharplogcat sharp_log_file:dir rw_dir_perms;

allow sharplogcat sharp_log_file:file { create read open write append rename getattr setattr rw_file_perms };

allow sharplogcat logdr_socket:sock_file { write };

allow sharplogcat logd:unix_stream_socket { connectto read };

2. file_contexts,该文件用于为文件分配标签,并且可供多种用户空间组件使用。在创建新政策时,请创建或更新该文件,以便为文件分配新标签:

/(vendor|system/vendor)/bin/sharplogcat u:object_r:sharplogcat_exec:s0

SELinux 相关设置

SElinux共有两种等级可以设置,可通过getenforce查看

- 宽容模式(permissive) - 仅记录但不强制执行 SELinux 安全政策。

- 强制模式(enforcing) - 强制执行并记录安全政策。如果失败,则显示为 EPERM 错误。

1.临时关闭

setenforce 命令修改的是 /sys/fs/selinux/enforce 节点的值,是 kernel 意义上的修改 selinux 的策略,缺点是断电之后,节点值会复位。

setenforce 0

2.永久关闭

第一种方法:修改system/core/init/Android.mk

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))

#HISILICON add begin

#reboot. Disable dumping when rebooting in non-user mode.

init_options +=

-DALLOW_LOCAL_PROP_OVERRIDE=1

-DALLOW_PERMISSIVE_SELINUX=1  //1:permissive

-DREBOOT_BOOTLOADER_ON_PANIC=1

-DDUMP_ON_UMOUNT_FAILURE=0

#HISILICON add end

else

init_options +=

-DALLOW_LOCAL_PROP_OVERRIDE=0

-DALLOW_PERMISSIVE_SELINUX=1  //1:permissive

-DREBOOT_BOOTLOADER_ON_PANIC=0

-DDUMP_ON_UMOUNT_FAILURE=0

endif

第二种方法:修改system/core/init/init.cpp,需要重新编译boot分区并烧录该分区。

static bool selinux_is_enforcing(void) //直接注释掉内容,reture false即可。

{

if (ALLOW_PERMISSIVE_SELINUX) {

return selinux_status_from_cmdline() == SELINUX_ENFORCING;

}

return true;

}

第三种方法:开机时修改bootargs。开机时不断Ctrl+c进入fastboot模式,printenv获取当前参数配置,修改其中androidboot.selinux=permissive,再setenv->saveenv->reset即可。

bootargs=selinux=1 androidboot.selinux=permissive firmware_class.path=/vendor/firmware/ console=ttyAMA0,115200 loglevel=7 no_console_suspend blkdevparts=mmcblk0:1M(fastboot),1M(bootargs),40M(recovery),8M(panelparam),2M(deviceinfo),38M(logo),2M(btfw),40M(kernel),1M(dtb),2M(atf),25M(trustedcore),10M(securestore),1M(versioninfo),1M(misc),3072M(system),300M(vendor),50M(atv),50M(db),2048M(cache),-(userdata) mtdparts=hi_sfc:-(hi_sfc) pci=nomsi mem=3072M dma_zone=2G mmz=ddr,0,1996M,48M mdlid=0 cmode=0 finit=0 panelsize=0 androidboot.sharp.serialno= androidboot.productname=--

ver=Fastboot 3.3.0-00015-g327655d-dirty (build@serd-build-008) (Mar 18 2019 - 09:17:15)

在实际的开发中,配置selinux是非常繁琐和枯燥的,但是作为官方推广的安全策略,还是希望大家能够了解一些,以上就是本文的全部内容,希望对大家的学习有所帮助。

你可能感兴趣的:(Android安全策略Selinux小结)