TrustZone、Seccomp、SELinux简介

TrustZone简介

1. TrustZone是什么

TrustZoneARM的一种硬件架构,其简介可以在ARM的官方网站上找到ARM的官方网站

ARM TrustZone创建了一个孤立的Secure World,可用于为系统提供机密性和完整性。它是通过划分所有SoCSystem on Chip,系统级的芯片)的硬件和软件资源为Secure World和Normal World两个世界来实现的。所有需要保密的操作在Secure World执行(如身份验证,支付认证等),其余操作在Normal World执行(如用户操作系统、各种应用程序等),普通区域组件无法访问安全区域资源,所以攻击者无法获取Secure World的敏感信息。Secure WorldNormal World通过Monitor Mode的模式进行转换,如图1.1所示。
TrustZone结构图
​ 受它保护的硬件,就算黑客root了你的设备也没办法访问的,只有生产者自己写的trust app才能访问。在操作系统之上自然要有应用程序,在Trustzone里面我们一般叫TrustApp,当然TEE(可信执行环境)里面每个TrustApp都在一个沙盒里,互相之间是隔离的。比如说支付,就可以做成一个App(需要注意的是,和Normal World里面的App是两个概念),这个App简单来说就负责用私钥把网上发来的Challenge签个名,而这个签名的动作是需要在Secure World里面做的,避免恶意程序窃取到私钥来伪造签名。

ARM TrustZone技术提供基础设施基础,允许SoC设计人员从一系列可以在安全环境中实现特定功能的组件中进行选择使用。

2. TrustZone是怎么做的

这种架构在ARM上体现为如下几点:
在这里插入图片描述

硬件上

  1. the core AXI bus:AXI总线,增加一条控制线。

  2. ARM core,可支持虚拟化核

  3. Trust zone Address Space controller:TZASC

  4. Trust zone protection controller:TZPC

  5. The TrustZone Memory Adapter TZMA,APB-to-AXI是可选的看SOC是否支持保护外设功能

其中1、2是针对Secure World、Normal World的隔离,3是针对内存的隔离,4是针对外设的隔离。

软件上

软件上就是基于第二点可虚拟化核心,加上SMC系统调用,可进行Secure World和Normal World的切换。

2.1 AMBA3 AXI–总线结构

AXI(Advanced eXtensible Interface)是一种总线协议,该协议是ARM公司提出的AMBA(Advanced Microcontroller Bus Architecture)3.0协议中最重要的部分。

AXI协议是定义了以下5个独立的传输通道:读地址通道、读数据通道、写地址通道、写数据通道、写响应通道。AXI总线上每个读写信道都增加了一个额外的控制信号。

  • ARPROT[1]: 用于读操作,低表示Secure World, 高表示Normal World

  • AWPROT[1]: 用于写操作,低表示Secure World,高表示Normal World

当设备向总线提出读写请求时必须将控制信号发送到总线上,总线根据这个信号和CPU当前的世界来判断能否读写,从而控制不安全设备对安全资源的访问。如:硬件设计上,所有Normal World的主设备在操作时必须将信号的NS控制位设置为1,而NS位置为1是无法访问总线上Secure World的从设备的,所以Normal World主设备发出的地址信号进行解码时在Secure World中找不到对应的从设备,从而导致操作失败。

2.2 ARM core—虚拟化

​ TrustZone中,将物理处理器分时复用虚拟为一个安全核和一个非安全核,安全核运行Secure World的代码,非安全核运行Normal World的代码,另外还有一套专门的机制提供状态的切换。

​ 基于TrustZone的系统有三种状态,Secure World、Normal World和用于二者切换的Monitor Mode。支持trustzone的ARM处理器的协处理器CP15的寄存器SCR有一个NS控制位用于指示当前处理器位于哪一个世界,该寄存器在Normal World是不能访问的。如果NS=0,系统处于安全状态,NS=1,系统处于非安全状态。当CPU处于Monitor Mode时,无论NS位是0还是1,处理器都是在Secure World运行代码。因此Monitor Mode下总是Secure World,但如果此时NS为1,访问CP15的其它寄存器获取到的是其在Normal World的值。

Secure World到Normal World的切换

​ 将CP15的NS位置1,Secure World可以直接跳转到Normal World,由于此时CPU的流水线和寄存器还遗留了Secure World的数据和设置,非安全模式下的应用可以获取到这些数据,会有极大的安全风险。因此,只建议在Monitor Mode下通过设置NS位来切换到非安全模式

Normal World到Secure World的切换

Normal World无权访问CP15的SCR寄存器,所以无法通过设置NS来直接切换到Secure World,只能先转换到Monitor Mode,再到Secure World

​ 从Normal WorldMonitor Mode的操作可通过以下方式触发:软件执行SMC (Secure Monitor Call)指令、硬件异常机制的一个子集。SMC是一个特殊指令,类似于软件中断指令(SWI),通过它来进入mointor模式。

2.3 TZASC–内存隔离

这里的内存指外部的DDR和片上的ROM以及SRAM,其隔离和保护通过总线组件TZASCTZMA的设置来实现。

TZASC是地址空间控制器,它可以把内存地址空间划分一系列的内存空间,通过运行在Secure World的软件把部分空间配置为安全、非安全的,防止非安全设备访问安全内存空间。

TZMAAXI总线的主设备,用它来划分片内SRAMROM的安全区间

2.4 TZPC—外设隔离

外设上,基于APB总线的设备不支持AXI总线的NS控制信号,所以AXI到APB总线需要AXI-to-APB bridge设备连接,除此之外,还需要TZPC (TrustZone Protection Controller) 来向APB总线上的设备提供类似AXI上的NS控制信号。

3. 怎么保证启动系统是安全的

系统上电复位后,先从Secure World开始执行。Secure World会对Normal Worldbootloader(功能类似BIOS,存在于嵌入式系统)进行验证,确保Normal World执行的代码经过授权而没有被篡改过。然后Normal World的bootloader会加载Normal World的OS,完成整个系统的启动。

在非安全系统的bootloader加载OS时,仍然需要Secure World对OS的代码进行验证,确保没有被篡改。

4. 参考

1.https://developer.arm.com/technologies/trustzone?_ga=2.61525864.51812845.1539486224-914019067.1539486224

2.https://blog.csdn.net/Alex___Zhao/article/details/76647377

3.https://blog.csdn.net/guyongqiangx/article/details/78020257

4.https://blog.csdn.net/hovan/article/details/42520879

Seccomp简介

1. 什么是Seccomp?

seccompsecure computing 的缩写,其是 Linux kernel 从2.6.23版本引入的一种简洁的 sandboxing 机制。

系统调用:

Linux中,将程序的运行空间分为内核与用户空间(内核态和用户态),在逻辑上它们之间是相互隔离的,因此用户程序不能访问内核数据,也无法使用内核函数。系统调用就是一种特殊的接口。通过这个接口,用户可以访问内核空间。系统调用规定了用户进程进入内核的具体位置。

具体步骤:用户进程–>系统调用–>内核–>返回用户空间

在 Linux 系统里,大量的系统调用(system call)直接暴露给用户态程序。但是,并不是所有的系统调用都被需要,而且不安全的代码滥用系统调用会对系统造成安全威胁。seccomp安全机制能使一个进程进入到一种“安全”运行模式,该模式下的进程只能调用4种系统调用(system call),即 read(), write(), exit() 和 sigreturn(),否则进程便会被终止。

  • Write():

    • 函数定义:ssize_t write (int fd, const void * buf, size_t count);
    • 函数说明write()会把参数buf所指的内存写入count个字节到参数放到所指的文件内。
    • 返回值:如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。
  • Read()

    • 函数定义:ssize_t read(int fd, void * buf, size_t count);
    • 函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。
    • 返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。若参数count 为0, 则*read()*不会有作用并返回0。
  • Exit()

    • 函数说明:终止进程
  • ***sigreturn()***:信号用于在用户态进程间通信。内核也用信号通知进程系统所发生的事情。这个sigreturn()在调用完成返回用户态时,清理堆栈,以便进程可以从信号中断的位置重新启动。

2. 如何使用

  • seccomp可以通过系统调用ptrctl(2)或者通过系统调用seccomp(2)开启,前提是内核配置中开启了CONFIG_SECCOMPCONFIG_SECCOMP_FILTER

  • seccomp支持两种模式:SECCOMP_MODE_STRICTSECCOMP_MODE_FILTER。在SECCOMP_MODE_STRICT模式下,进程不能使用read(2)write(2)exit(2)sigreturn(2)以外的其他系统调用。在SECCOMP_MODE_FILTER模式下,可以利用BerkeleyPacket Filter配置哪些系统调用及它们的参数可以被进程使用。

SELinux简介

1. 概述

  • SELinux起源于1980年开始的微内核和操作系统安全研究,该研究形成了Distribute Trusted Mach(DTMach),它包含了一组安全内核类型强制
  • 美国NSA参加了DTMach项目,产生了Flask: Flux Advanced Security Kernel,支持更为丰富的动态类型强制机制
  • 1999年夏天NSA开始在Linux内核实现Flask安全架构
  • 2000年十二月,NSA公布了第一个公开版本,被称为SELinux
  • 2001年Linux内核高级安全会议上,Linux Security module, LSM开始为内核创建灵活的框架,允许不同的安全扩展添加到Linux
  • 为了与LSM一起工作,NSA开始修改SELinux使用LSM框架,
  • 2002年八月LSM被集成到Linux主线,2003年八月完成了SELinux到LSM的迁移,进入到Linux2.6的内核主线
  • NSA在SELinux的基础上实现了SEAndroid

2. 类型强制访问控制

  • 在SELinux中,所有访问必须明确授权,默认不允许任何访问
  • SELinux通过使用allow规则授予访问权限

2.1 Allow规则

规则组成

  • 源类型(source Types):尝试进行访问控制的域类型(历史原因,进程类型通常被称为域类型)
  • 目标类型(Target Types):被进程访问的客体类型
  • 客体类别(Object class):允许访问的客体的种类名称
  • 许可(Permissions):目标类型允许源类型访问的种类
  • 举例
    • Allow user_t bin_t: file{read execute}
      • 源类型为:user_t(类型一般以_t结尾)
      • 目标类型为:bin_t
      • 客体类别:file,表示客体为普通文件
      • {}内的信息标示:客体访问许可的子集
      • 以上规则标示:拥有域类型user_t的进程可以读、执行具有bin_t类型表示的文件的权限

2.2 audit规则

审核消息通常叫做"AVC消息",它提供了详细了关于访问尝试的信息,包括是允许还是拒绝,源和目标的安全上下文,以及其它一些访问尝试涉及到资源信息。AVC消息与其它内核消息类似,都是存储在/var/log目录下的日志文件中,它是策略开发、系统管理和系统监视不可缺少的工具。在此,我们检查是哪一个访问尝试产生了审核消息。

  • dontaudit:表示不记录违反规则的决策信息,且违反规则不影响运行(允许操作且不记录)
  • auditallow:表示允许操作并记录访问决策信息(允许操作且记录)

2.3 neverallow规则

  • 默认不允许任何访问,为什么还要有这个规则?
  • 为了帮助编写策略时,可以明确地指出不想要的访问许可。

3. 类型转换规则type_transition

域转换只是改变了进程现有的类型

支持默认域转换事件

支持客体转换,它允许我们指定默认的客体标记

Q:

当一个用户Alice登录系统时,系统将创建一个Shell进程。在SELinux中,用户Shell进程的类型是user_t,表示一个普通的、不受信任的用户进程域类型。那么SELinux下,用户Alice如何修改自己的密码呢?

  • 不能通过Allow规则,让非受信的user_t类型域直接访问shadow文件,否则安全将无法保证。
  • type_transition user_t passwd_exec_t: process passwd_t
    • 这个规则引发默认的域转变尝试,如果调用的进程域类型是user_t,并且可执行文件的类型是passwd_exec_t时,将会尝试到一个新域类型的转变

    • 该转变引发默认的域转变,不需要用户的明确输入

    • 这个规则仅引发一个默认的域转变,但是不允许它执行,需要三个allow规则

      • allow user_t passwd_exec_t : file{getattr execute}

        • 进程当前的域类型对于可执行文件具有执行权限
      • allow passwd_t passwd_exec_t : file entrypoint

        • entrypoint 权限:允许进程可以进入特定的域类型
        • 规则实例说明:要转变的目标域类型passwd_t具有访问类型为passwd_exec_t的可执行文件的entrypoint权限
        • 进程新的域类型对可执行文件具有entrypoint权限
      • allow user_t passwd_t: process transition

      • 这是一条没有文件客体的访问规则
      • 规则中的客体类别是process,代表进程
      • 权限transition允许进程修改进程的安全上下文
      • 原始的类型(user_t)到新的类型(passwd_t)进行域转变需要transition权限
      • 进程当前域类型对进程新的域类型具有transition权限

猜你喜欢

转载自blog.csdn.net/weixin_43255133/article/details/83052044