基于ARM指针认证的信息流控制系统
2021-07-26张立强陈青松
张立强,陈青松,严 飞
(武汉大学 国家网络安全学院 空天信息安全与可信计算教育部重点实验室 湖北 武汉 430072)
0 引言
物联网是一种人、机、物广泛互联的实体系统,通过智能感知、识别技术与普适计算、泛在网络的融合应用,对物理世界进行智能化识别和管理[1]。物联网技术的高速发展改善了个人和公共生活的诸多方面,其应用范围涵盖智能家居、病人监护、工业自动化、智慧交通和基础设施监控等。Gartner调查报告表明,2018年全球已有91亿物联网设备投入使用(复合增长率20.9%),预计2025年联网数量将达到251亿[2]。由于物联网平台通常建立在数据采集处理的基础上,而物联网设备直接暴露于互联网,易于遭受网络攻击[3],因此,用户隐私遭受着较大的泄露风险。
为了保护物联网设备的数据安全,通常采用密码技术[4]和访问控制技术[5]这两种方案。密码技术主要通过数据加密和数字签名来保护数据的机密性和完整性;访问控制则是以授权策略为核心,防止主体对客体的未授权访问和使用。传统访问控制模型包括自主访问控制(discretionary access control, DAC)和强制访问控制(mandatory access control, MAC)。DAC利用访问控制列表和能力系统等,允许数据所有者修改对数据的访问权限,其安全检查容易被绕过;MAC则依赖于在硬件层面或者系统层面实施的一组安全策略,基于主体和客体的安全标签限制主体对客体的访问能力。
分散式信息流控制(decentralized information flow control, DIFC)属于MAC模型,最早由Myers等于1997年提出[6],现有研究工作主要集中在对该模型的应用和实现上。HyperFlow提供了一种处理器设计方法[7],使用强制执行信息流控制的安全类型硬件描述语言实现,可以从处理器架构上提供基于运行时安全策略的信息流控制,并在一定程度上抑制微体系结构侧信道。Flume通过拦截系统调用来执行进程间信息流控制,需要对Linux内核进行一定的修改,被标记的进程只能访问受限的系统调用[8]。AT-DICF是Flume的扩展,通过将系统模块组织为信任上下文的层次结构,利用多个分散的信任控制器在操作系统中实施细粒度的安全策略[9]。Weir在Android系统上提供了向后兼容的DIFC实现,通过接管应用程序及其组件的创建和通信,允许应用更改各自的标签来设置安全策略,从而控制应用数据到网络的流入[10]。Fabric提供了一种用于构建支持信息流控制的分布式应用程序的高级编程语言,通过类型注释来控制代码和数据的标签,使安全计算和存储以及跨信任边界共享代码和数据成为可能[11]。CamFlow是针对分布式云环境的信息流控制系统,其原型系统假设云服务提供商是一个非恶意实体,无法保证数据在进入和离开系统时的安全性[12]。DDIFT为物联网小程序的隐私安全提供了一种粗粒度信息流跟踪框架,针对URL上传攻击可以提高识别程度并减少资源浪费[13]。DFLATE[14]可以对分布式可信执行环境中的代码进行可信度量,并进行了形式化证明;它使用了强无干扰机密性模型和弱无干扰完整性模型,因此无法防止高完整性的信息对系统的恶意行为。
以上工作对隐私数据保护具有一定的贡献,但对于资源受限的物联网应用场景来说,存在一些限制,主要表现在三个方面:
1)基于定制硬件或操作系统的方案存在兼容性的问题,无法进行快速移植;
2)用户层实现的DIFC机制,运行时内存占用和性能开销较大,对信息流的跟踪效率较低;
3)由于物联网应用通常在单个进程中生成和分析敏感数据,粗粒度的进程级防护难以实施有效的数据隔离保护。
上述问题导致现有的系统仍然面临着以下威胁:不安全的第三方库和特权函数可以被用来泄露应用隐私数据;多线程应用中,某个线程中的漏洞可以被用来泄露其他线程中的隐私数据[15]。为了解决这些问题,本文结合了密码技术和访问控制技术的优点,提出了一种基于ARM指针认证的线程防御方案(pointer authentication based thread scheme,简称PATS),基于DIFC模型轻量高效地实现了线程级的安全隔离和隐私数据保护。本文的主要贡献包括:
1)设计并实现PATS,利用ARM体系中的轻量级指针签名认证方案,对线程添加安全标签和完整性标签,实现细粒度的数据隔离和多线程保护;
2)对PATS的原型系统进行评估,结果表明PATS具有较小的内存占用和运行时开销,适用于资源受限的物联网设备;
3)基于PATS的用户空间接口,对实际的应用OpenSSL进行移植,表明PATS具有良好的兼容性和可移植性,仅引入了合理且可接受的性能开销。
1 背景知识
1.1 ARM指针认证
近年来,基于硬件辅助的安全方案逐渐流行[16],ARM公司也在ARMv8.3-A中引入了指令集安全扩展——指针认证(pointer authentication,PA),通过指针认证码(pointer authentication code,PAC)提供一种高效的机制,检测攻击者对代码指针或数据指针的恶意修改[17]。PAC是一种密钥相关的哈希运算消息认证码,它存储在64位原始指针的高位,无须额外的内存空间。
指针认证机制主要引入了三种指令:1)PAC*指令用于生成PAC并将其插入原始指针的高位;2)AUT*指令旨在对PAC进行认证,如果PAC匹配,则返回原始指针,否则返回无效指针,该指针将在使用时触发异常;3)XPAC*指令则直接返回原始指针,不需要认证过程,主要用于监控和调试。如图1所示,PAC*指令需要三个参数,64位的原始指针VA、64位上下文参数M和存储在系统寄存器中的128位密钥K,然后使用默认的QARMA算法生成PAC,其大小受到虚拟地址长度和ARMv8.5-A引入的内存标记扩展(memory tag extension, MTE)[17]的限制。例如,在虚拟地址为48位并启用MTE的系统中,PAC大小仅为7位。因此,PAC可以被当作一种轻量高效的标签,用来跟踪保护数据指针的完整性。另外,如果为每个线程生成不同的密钥,可以对每个线程的私有数据进行访问控制。
图1 PAC生成算法
1.2 分散式信息流控制
DIFC模型针对互不信任、分散式的环境,使用主体和标签来追踪和控制数据的流动,避免数据泄露的风险[6]。主体是数据的拥有者,有权修改数据内容和授权;标签是一组安全策略的集合,它表达了不同主体的隐私需求。标签的基本结构为
L={owner1:readers1;…;ownern:readersn}。
一个策略由一个owner和一个readers集合组成,readers是owner授权的主体集合,没有被owner列为readers的主体不允许访问owner的私有数据。使用标签的概念来标记数据,不仅可以追踪数据在系统中的流动过程,还可以使一个主体定义和控制自己的安全策略,控制主体对数据的访问,并可以在不干扰其他主体安全策略的前提下,通过对标签的解密来减少对数据的安全约束,从而允许临时访问保密数据,增加了系统的灵活性。
现有的研究工作,要么基于定制硬件或操作系统,存在兼容性的问题,无法进行快速移植;要么在用户层由软件实现,运行时内存占用和性能开销较大。因此,本文利用ARM指针认证技术对线程地址空间进行标记,并为每个线程添加安全标签和完整性标签,从而使每个线程可以定义和控制自己的安全策略,而这些安全策略则由内核安全原语进行强制安全检查,实现线程级的安全隔离和信息流控制。
2 系统设计
本节介绍基于ARM指针认证的线程级信息流控制系统PATS的威胁模型、整体架构、访问控制机制以及相关管理接口。
2.1 威胁模型
PATS的威胁主要来自两个方面:一是共享地址空间内由脆弱或恶意第三方库的内存破坏漏洞引起的隐私数据泄露;二是多线程程序中某个线程本身的逻辑错误或漏洞(例如,缓冲区溢出或ROP攻击)被用来攻击其他线程的隐私数据。
本文假设攻击者可以控制多线程程序中的某些线程并分配内存,也可以通过操作系统接口产生更多线程,直至资源限制。攻击者可以尝试通过已控制的线程来提升权限,或者尝试通过修改另一个线程的数据或注入代码来获得对另一个线程的控制,以及尝试通过线程之间的竞争条件来绕过隔离保护。目前,PATS并不提供基于共享硬件资源(例如,缓存和TLB)的侧信道攻击的保护,但可以与Nickel[18]等系统集成提供相应的保护。
2.2 系统架构
PATS旨在为物联网设备提供一个轻量高效的线程级访问控制解决方案,应能满足以下设计需求。
1)隔离性需求。每个线程都应该能够定义其安全策略和信任模型,从而有选择地保护和共享其隐私数据。
2)可用性需求。PATS应该足够轻量(文件大小与内存占用),从而能在资源受限的设备上运行。PATS提供的接口应该具有较小的性能开销,且未使用PATS的不可信部分不应该承受任何开销。
3)兼容性需求。PATS应该提供兼容大部分物联网操作系统的解决方案,并提供简单的用户空间接口,从而方便应用快速移植。
如图2所示,PATS将一段由PAC标记的地址空间(PACed address space,PAAS)视为安全主体,并将管理PAAS的线程(PACed thread,PAT)视为隔离单元,对其添加安全标签和完整性标签。每个PAT可以管理多个PAAS,通过安全标签和完整性标签,PAT可以针对PAAS定制各自的安全策略,并由操作系统内核强制执行安全检查与授权,实现内存共享和隐私数据保护。
图2 PATS整体架构
2.3 访问控制
PATS基于DIFC的动态安全策略,通过修改两个内核对象,地址空间PAAS和线程PAT,来实施最小特权原则。PAAS是进行内存管理和隐私数据保护的最小单元,由ARM指针认证机制进行签名和认证。PAT可以管理多个PAAS,用来存储隐私数据或者通过共享内存通信。每个线程t都拥有自己的安全标签SLt和完整性标签ILt,标签的定义为
L={paas1:tids1;…;paasn:tidsn}。
PAT通过标签定义了所管理的PAAS的安全策略,其中,paas表示地址空间的结构体指针,指向该PAAS的ID、起始地址、长度、内存权限等;tids则表示该PAAS被授权的线程集合。每个PAAS可以被授予的能力有两种:C+表示向标签添加该PAAS的能力,也表示PAT可以获得该PAAS拥有者所设置的访问权限(读、写或执行);C-则表示从标签中删除PAAS的能力,也表示PAT可以获得解密该PAAS的权限,即在不影响其他PAT安全策略的前提下修改自身的安全策略(修改被授权的线程集合tids)。同时,所有的访问控制策略都需要在内核执行,例如线程α和β的安全标签和完整性标签分别为SLα和ILα以及SLβ和ILβ,当SLα⊆SLβ时,才允许从线程α到β满足机密性要求的信息流;当ILα⊆ILβ时,才允许从线程β到α满足完整性要求的信息流。而当线程将其自身的标签从La更改为Lb时,必须满足条件
其中:Ct表示线程t所拥有的能力集合,对于Lb中存在但La中不存在的PAAS,线程t需要拥有添加相应的(paas,tids)对的能力;对于La中存在但Lb中不存在的PAAS以及两个标签中都存在但授权集合不一致的PAAS,线程t需要拥有删除该PAAS的能力,即修改授权集合tids。
2.4 管理接口
为了方便管理线程间的访问控制权限和应用的快速移植,PATS提供了必要的系统调用接口和简单的用户空间接口,分别用于线程管理和内存管理。
线程管理主要包括线程的创建以及针对其拥有的PAAS的权限管理,如表1所示。每个PAT可以管理多个PAAS,默认情况下,从PAT创建子线程时不会继承其所管理的PAAS,必须显式地调用pat_clone函数表明需要传递给子线程的PAAS。同时,在运行过程中,PAT也可以通过pat_transfer_caps函数向其他线程传递自己所拥有的PAAS,并授予C+或C-能力;而当PAT想取消某个PAAS的授权时,可再次调用该函数,重新进行授权。拥有C-能力的PAT可通过pat_declassify函数解密对应的PAAS,从而在不影响其他PAT安全策略的前提下修改其安全策略,例如,PAT可以代表该PAAS的拥有者对其他PAT授予PAAS的访问权限。为了限制对相同PAAS拥有访问权限的PAT之间可能产生的竞争条件,PAAS的拥有者可以通过调用pat_lock和pat_unlock函数,临时修改该PAAS的标签,限制其他PAT的访问和代表授权。
值得注意的是,为了防止攻击者恶意修改PAAS的标签,所有标签的关键数据结构都应在内核空间进行管理,暴露给用户空间的只有与PAAS关联的ID(表1所示系统调用由相似的用户空间接口进行封装,隐藏了真实的标签数据),如表2所示。线程通过paas_create函数创建一段连续的地址空间,通过paas_get函数查看PAAS当前的属性,然后通过paas_mprotect函数修改其内存属性,最后可通过paas_destroy函数销毁该PAAS,回收内存。为了更有效管理内存,paas_create函数创建的PAAS默认是1 MB对齐的,如果需要更少的内存,可通过paas_malloc函数从PAAS中进行内存分配,并通过paas_free释放申请的内存。从PAAS中分配的内存地址仍然使用ARM指针认证进行标记,防止其他线程对其进行恶意访问。
表1 PAT访问控制系统调用
表2 PAAS内存管理接口
PATS绕过了传统Linux内核的虚拟内存管理,提供了一套新的安全管理原语,并在传统的管理接口中添加了自定义的安全检查钩子,以实施PAT的安全策略,检查标签的正确流向。PATS还提供了单独的异常处理程序,用于记录并中止针对PAAS的非法访问。
3 系统评估
目前市场上除了Apple公司的A12 Bionic SoC等(私有实现),没有其他支持ARM指针认证的硬件实现,因此本文采用ARM公司提供的虚拟仿真平台(fixed virtual platforms, FVP)[19]对PATS原型系统进行测试,并基于Yocto项目[20]构建根文件系统和64位Linux 5.4.23版本内核镜像。
3.1 系统实现
本文基于Linux安全模块(Linux secure module, LSM)实现了用于执行安全策略的内核钩子和用于执行访问控制的系统调用(如表1所示,仅列出了部分接口)。安全钩子被添加到内核中的相关位置,主要包括POSIX接口(例如mmap、mprotect和fork等)和表2所示的用户空间接口,防止PAAS受到未经授权的访问或权限更改。例如,当PAT创建子线程时,不应该复制其标签和能力列表;使用POSIX接口进行内存管理时,应该限制其访问PAAS中的隐私数据,并限制对PAAS的权限更改。PAAS的标签基于ARM指针认证生成,且每个线程使用不同的密钥来计算标签值,因此,本文还修改了任务结构体task_struct用来存储必要的元数据。
为了提供简单的用户空间接口并减小可信计算基的大小,本文没有修改现有的系统库(如glibc),而是实现了一个轻量级的用户空间库,为应用提供了线程管理和内存管理的接口;并实现了自定义的内存分配器,用于分配小于1 MB的内存。
PATS是面向物联网设备的信息流控制系统,本文实现的原型系统仅包含针对Linux内核的补丁文件,不依赖任何第三方库。PATS向内核空间增加了约2 500行代码,向用户空间增加了约2 000行代码。基于Yocto项目编译出的最小内核镜像,文件大小上增加了约7 kB,运行时内存占用增加了约210 kB,用户空间内存占用约20 kB。以上结果表明,PATS的内存占用较低,适用于资源受限的物联网场景。
3.2 性能开销
本文通过测试内存相关操作和多线程操作来评估PATS的运行时性能开销。
对于内存相关操作,由于paas_create函数创建的PAAS是1 MB对齐的,当申请的内存大于1 MB时,与常规的mmap调用相比,PATS的性能开销仅存在于为地址空间分配标签,平均时延增加了4.4%;当申请的内存小于1 MB时,PATS通过自定义的内存分配器在PAAS内部分配内存,实验结果如图3所示。
图3 内存分配时延
对于小于128 kB的块,使用PATS的内存分配器的平均时延比glibc提供的malloc函数小6.0%,而对于大于128 kB的块,PATS的内存分配器的平均时延则要大7.8%,这是因为malloc函数对于两种情况分别使用brk和mmap系统调用来进行内存分配。对于修改内存属性,paas_mprotect函数由于要进行额外的标签操作,平均时延比mprotect函数大15%。
对于多线程操作,本文分别测试了pat_clone、pthread_create和fork等函数的运行时开销(创建和等待子线程过程)。其中,pat_clone内部过程类似clone系统调用,不同的是,pat_clone限制了与子线程共享的内存资源(不再共享整个地址空间),同时提供了向子线程传递PAAS的功能。由于pat_clone默认不共享任何PAAS,因此本文分别测试了默认情况和共享一个PAAS的情况下的性能开销,分别用pat_clone0和pat_clone1表示,如图4所示。
图4 线程创建时延
默认情况下,pat_clone的平均时延比pthread_create小0.47%,比fork小84.8%。和子线程共享一个PAAS的情况下,pat_clone的平均时延则比pthread_create大18.5%,比fork小81.9%。总的来说,PATS提供的多线程操作开销较小甚至优于传统的fork调用,这得益于pat_clone的最小共享策略,取消了创建子线程时不必要的共享操作。
4 用例分析
为了评估PATS的兼容性和应用程序的移植难度,本文对OpenSSL进行了适当修改,利用PATS提供的用户空间接口保护其敏感数据。
OpenSSL是一种广泛使用的开源安全套接层协议库,应用程序可以使用它来进行加密通信,防止被攻击者窃听。OpenSSL负责处理敏感数据,例如会话密钥和通信数据。因此,将这些敏感数据存储在线程安全的地址空间PAAS中可以降低遭受攻击(如“心脏滴血”漏洞)时,敏感数据泄露的风险。
为了在OpenSSL中启用PATS,本文将所有与会话密钥相关的数据结构(如EVP_PKEY等)都通过PAAS进行内存分配和存储,这意味着,需要用paas_malloc替换OpenSSL_malloc函数,并在初始化阶段使用paas_create函数创建一个或多个PAAS来存储相关数据。对于每个PAAS内的数据,OpenSSL可以使用pat_lock禁用其他线程的访问,只有需要访问会话密钥的函数,例如,EVP_EncryptUpdate或pkey_rsa_encrypt等,才允许通过调用pat_unlock函数对PAAS进行解锁。基于PATS的OpenSSL版本与开源版本相比,仅修改或新增了273行代码。
同样,本文基于虚拟仿真平台FVP和Yocto项目构建的根文件系统,并选择Apache HTTP服务器(httpd)作为测试平台进行用例分析。实验结果如图5所示,分别展示了使用原始OpenSSL库和基于PATS的OpenSSL库(包括对所有会话使用相同PAAS存储密钥的版本,和对每个会话使用不同PAAS的版本)的性能开销。
图5 ApacheBench测试结果
实验结果表明,使用单个PAAS保护会话密钥时,平均性能开销为0.68%;而对每个会话使用不同的PAAS时,平均性能开销为3.66%。使用单个PAAS的性能开销主要花费在维护内核数据结构上,这些数据主要用于执行安全策略;而使用多个PAAS的性能开销则主要花费在创建PAAS的过程,以及多线程间的标签传递与检查。总的来说,这些开销都是合理且可接受的。
5 结束语
本文设计实现了一个针对资源受限的物联网设备的信息流控制系统PATS,利用ARM指针认证机制对地址空间进行标记,并为线程添加安全标签和完整性标签,实现线程级的隔离和内存保护;基于Linux安全模块实现的访问控制和安全检查钩子,可以保证安全策略的有效执行,防止线程间潜在的隐私数据泄露风险。评估表明,PATS具有较小的内存占用和运行时开销;同时,实际的用例程序(OpenSSL)也表明PATS具有良好的兼容性和可移植性,适用于物联网设备等资源受限的场景。对于单线程程序(例如,事件驱动的服务器),攻击者如果可以感知并利用PATS相关的用户空间接口,PATS仍然存在被绕过的风险。对于更细粒度的保护,在未来工作中,可以利用ARMv8.5-A引入的内存标记扩展MTE对16字节对齐的内存添加标签实现信息流的控制。