2. INTEGRITY系统架构与测试对象解析

INTEGRITY实时操作系统在安全关键领域被广泛采用,其核心设计目标是在同一硬件平台上同时承载多个不同安全等级的应用,并保证它们之间不会发生越权访问或时间干扰。要理解测试对象和测试接口,必须先理解它的架构骨架:分离内核、内存保护、分区调度与安全策略四者共同构成了一个"空间隔离+时间隔离+策略约束"的立体防护体系。测试工作正是围绕这四层机制展开的。

分离内核:最小可信计算基

INTEGRITY的分离内核(Separation Kernel)是整个系统的可信计算基(TCB),它只负责最基础、最关键的资源管理:地址空间切换、分区调度、进程间通信(IPC)路由、中断分发和对象访问仲裁。内核本身不包含文件系统、网络协议栈或设备驱动,这些都以用户态服务的形式运行在独立分区中。这种"微内核"式设计带来的直接后果是:内核代码量小、可验证性高,但系统功能被拆散到多个分区,测试时必须区分"内核行为"与"分区内行为"。

从测试角度看,分离内核暴露的接口非常有限,主要包括:系统调用(如对象创建、IPC发送/接收、分区启动)、中断入口、以及内核配置表。测试内核时,重点不是功能覆盖,而是验证其隔离机制是否被正确执行——例如,一个分区能否通过非法系统调用访问另一个分区的内存,或者能否绕过调度器抢占CPU时间。

内存保护:空间隔离的实现

INTEGRITY为每个分区分配独立的地址空间,由MMU(内存管理单元)强制隔离。分区内的代码和数据只能访问本分区映射的物理页,任何跨分区访问都会触发异常并被内核拦截。内存保护还延伸到栈保护、只读代码段、以及内核对象句柄的权限检查。

测试内存保护时,需要构造三类典型场景:第一,合法访问——分区读写自己的数据区,应正常执行;第二,越界访问——分区试图读写相邻分区的地址,应触发保护异常并记录;第三,权限提升——分区试图通过伪造句柄或修改页表来获取更高权限,应被内核拒绝。测试接口通常包括内存映射表、异常处理入口和内核日志。一个常见的测试用例是:在分区A中定义一个指向分区B数据区的指针,执行写操作,观察系统是否产生内存保护异常并终止分区A,而不是静默写入。

分区调度:时间隔离与确定性

INTEGRITY采用时间分区调度(Time Partition Scheduling),每个分区被分配固定的时间窗口,按周期循环执行。例如,一个周期为20ms的调度表可能包含:分区A在0-5ms执行,分区B在5-12ms执行,分区C在12-20ms执行。分区内再通过优先级抢占式调度管理任务。这种两级调度保证了分区之间的时间隔离:即使分区B内的任务死循环,也不会影响分区A和C的窗口。

测试分区调度时,核心是验证时间窗口的准确性和隔离性。需要测量的参数包括:窗口起始抖动、窗口执行时长偏差、分区切换开销、以及超时处理。测试接口包括调度表配置、分区执行计数器、时间戳寄存器和内核跟踪缓冲区。一个实用的测试方法是:在分区A的窗口内插入一个忙等循环,使其执行时间超过分配窗口,观察内核是否在窗口结束时强制切换,并记录超时事件。如果分区A超时后分区B仍能按时获得CPU,说明时间隔离有效。

安全策略:访问控制与信息流

INTEGRITY的安全策略通过内核对象和访问控制列表实现。每个分区、进程、信号量、队列等都被抽象为内核对象,对象之间的访问必须经过策略检查。策略可以配置为:分区A只能向分区B发送IPC消息,但不能接收;分区C可以读取共享内存,但不能写入。这些策略在系统配置阶段静态定义,运行时由内核强制执行。

测试安全策略时,需要覆盖策略允许和策略拒绝两条路径。测试接口包括策略配置文件、IPC通道状态、以及审计日志。例如,配置策略"分区A→分区B允许,分区B→分区A拒绝",然后分别在A和B中调用IPC发送函数,验证A发送成功、B发送失败并返回权限错误。如果B发送成功,说明策略检查存在漏洞。

INTEGRITY 架构与测试对象关系图 分离内核 (TCB) 地址空间切换 · IPC路由 · 中断分发 · 对象仲裁 内存保护 (MMU) 分区地址空间隔离 越界异常 · 权限检查 分区调度 时间窗口 · 周期循环 超时强制切换 安全策略 对象访问控制 IPC方向约束 分区 A (高安全) 窗口: 0–5ms 地址空间: 0x1000_0000 分区 B (中安全) 窗口: 5–12ms 地址空间: 0x2000_0000 分区 C (低安全) 窗口: 12–20ms 地址空间: 0x3000_0000 IPC 允许 IPC 拒绝 测试接口:系统调用入口 · 内存映射表 · 调度表配置 · 异常处理入口 · IPC通道状态 · 审计日志 测试重点:隔离有效性 · 窗口准确性 · 策略执行正确性 · 异常可观测性

架构对测试范围与接口的影响

上述四层机制决定了INTEGRITY测试的三个基本特征。第一,测试范围必须分层:内核层测试关注隔离机制本身,分区层测试关注应用功能与分区配置的匹配性,系统层测试关注多分区并发时的时序和资源竞争。第二,测试接口高度依赖配置:调度表、内存映射、安全策略都是静态配置的,测试用例必须与配置一致,否则无法触发目标路径。第三,可观测性有限:内核不提供通用调试接口,测试主要依赖异常记录、审计日志和分区内自检。

在实际项目中,一个典型的测试配置如下:三个分区,周期20ms,A窗口0-5ms、B窗口5-12ms、C窗口12-20ms;A→B IPC允许,B→C IPC允许,C→A IPC拒绝;A和B共享一段只读内存,C不可访问。测试时,先在A中构造越界写B地址空间的用例,预期触发内存保护异常;再在B中构造超时忙等,预期在12ms被强制切换;最后在C中尝试向A发送IPC,预期返回权限错误。三个用例分别覆盖内存保护、分区调度和安全策略,且都能通过异常日志和返回值判断结果。

测试INTEGRITY时,不要试图用通用Linux的测试思路去覆盖所有系统调用。它的接口面窄,但每个接口背后的隔离语义很强。把测试重点放在"隔离是否被破坏"上,比追求接口覆盖率更有效。

理解架构的另一个收益是:当测试失败时,能快速定位问题属于哪一层。例如,分区A在窗口内执行超时但未被切换,问题在调度配置或内核调度器;分区A能写入分区B的内存,问题在MMU映射或内核权限检查;分区C能向分区A发送IPC,问题在策略配置或内核对象仲裁。这种分层定位能力,是INTEGRITY测试工程师的核心技能之一。