基于真实硬件的操作系统安全实验设计

2024-06-03 11:35陈波何玲娜韩姗姗
中国信息技术教育 2024年10期
关键词:实验教学

陈波 何玲娜 韩姗姗

摘要:本文探索了基于开源硬件,教授低级安全概念的相关方法,包括与构建实践学习环境相关的尝试,并对嵌入式内核进行扩充,引导学生深入了解支持树莓派3B+上的系统调用和内存保护,且设计的作业旨在帮助学生深入了解复杂的硬件细节。最终教学结果表明,基于真实硬件设计操作系统安全实验,提供了一种培养学生分析和解决较复杂问题的有效方法。

关键词:操作系统安全;开源硬件;实验教学

中图分类号:G434  文献标识码:A  论文编号:1674-2117(2024)10-0090-05

引言

在硬件课程的教学中,真实硬件上的操作能够激发学生的好奇心,增强学生的成就感和参与度。然而,硬件课程对教室、教师、物料有着较高的要求,如在教授操作系统和计算机安全等课程时,由于商用操作系统的庞大,学生的学习范围被限制为单个组件或子组件,无法合理地呈现基于硬件的设计决策,而使用教学操作系统——用于观察和开发操作系统的组件则可以有效解决这一问题。因此,笔者尝试在操作系统安全课中引入嵌入式Xinu操作系统,并设计了系统服务及内存保护相关作业。

背景

嵌入式Xinu操作系统源自Xinu,其中心目标之一是让学生接触真实的硬件。现有嵌入式Xinu移植已用于嵌入式系统课程的教学,如移植到树莓派3B+上,允许硬件系统和操作系统课程提供多核执行的实践实验,但对操作系统安全方面的关注较少,没有实施明确的安全设施。

那么,如何设计一个操作系统,让它既能监督特权执行又能安全地操作用户线程?系统服务调用(Supervisor call,SVC)提供了此功能。SVC调用是非特权线程临时访问特权操作系统资源的接口。在arm架构上,系统模式功能强大,而用户模式受到限制,SVC在称为Supervisor模式的特权环境中执行。一般情况下,该模式具有与系统相同的高权限模式,而如修改CPU寄存器的指令,只能从特权模式访问。一个简单的操作系统(如教育操作系统)可能只包含几个SVC应用程序,生产操作系统则提供更多保护,但复杂度高。

嵌入式Xinu操作系统依赖GNU交叉编译器(GCC)来转换主要用C语言编写的内核源代码到一系列目标文件。这些目标文件链接在一起以创建可传输的最终可执行操作系统映像到受支持的机器上并运行。GCC等编译器有一组可用的优化选项,常见的优化程序的好处包括:更小的代码大小、更快的程序执行,且采用更少的分支(执行指令重新排序,在当前位置继续执行,而不是跳转到内存中较远的空间)。

系统服务调用SVC

笔者认为,学生应尝试硬件提供的保护设施,如基于模式的保护。一个处理器的执行模式定义了其当前状态,即它将用于执行svc等指令的方法。树莓派3B+的CPU有七种执行模式:系统模式、用户模式、管理员模式、中止模式、快速中断请求(FIQ)模式、中断请求(IRQ)模式、未定义模式。

在嵌入式系统课程中教授Embedded Xinu时,系统仅在System模式、IRQ模式或FIQ模式下执行。系统模式是特权模式,所有指令在此模式下均有效。对所有基本执行使用系统模式提供了优雅的设计,但是内置硬件安全设施未使用。当处理器在User模式下执行时,特权指令变得未定义。因为Pi 3B+的SoC没有公开可用的文档,很难准确确定哪些指令被认为是特权的,以及哪些在用户模式下可用。

Supervisor模式与系统模式一样,是一种特权模式,但它是一种异常模式,而系统模式不是。因此,要进入超级用户模式(或任何异常模式),处理器生成一个异常,该异常被Xinu的异常处理程序捕获。

管理员模式有自己的存储堆栈指针(一个跟踪运行时堆栈的寄存器)和链接寄存器(一个保存当前执行的函数完成时返回的指令地址的寄存器)。根据ARM调用约定,寄存器r0-r3在函数调用时被压入堆栈。当处理Supervisor模式异常时,使用其各自的堆栈来保存这些参数是有益的。因此,它的堆栈是在引导加载程序中初始化的。

当树莓派上电后,内核的bootloader会执行初始化步骤,如为每种潜在的执行模式准备堆栈内存。当处理Supervisor等异常时,平台要求相应的堆栈根据ARM过程调用标准进行8字節对齐。在开始执行由异常处理程序分支到的函数(如处理程序例程)之后,模式切换意味着堆栈指针已更新。

虽然树莓派3B+配备了四核处理器,但本课程使另外三个核心处于禁用状态。当不存在多核并发问题时,扩展内核变得更加简单。这对开发者有利,因为消除了对有关跨内核的系统调用的探索。这一决定也符合Xinu作为教学工具的用途。学生不必因与新硬件细节一起引入的多核系统而不知所措。

在嵌入式Xinu加载Null线程后,处理器仍处于系统模式(如图1)。 接下来是一些关键的初始化步骤。为了在网络传输后执行内核,必须首先初始化以太网设备,而树莓派平台的一个特点是网络通信通过USB设备进行,所以,首先要启用USB子系统。USB传输需要启用中断,因此整个过程在系统模式下进行。为了保持简单性,在主线程开始执行之前尽可能晚地进入用户模式。

SVC接口或系统调用接口是一种抽象,允许在非特权模式下运行的处理器安全地执行特权指令并返回到正常执行。图2显示了getcpuid()的系统调用序列,该函数返回当前处理器核心的数字标识。

svc指令是32位arm状态指令集和16位thumb指令集的一部分。为了区分所提供的内核服务,每个svc编号在头文件include/svc.h中唯一定义。

在使用USB(通用串行总线)设备等板载设备的嵌入式操作系统上,必须采用一种机制来促进操作系统和设备之间的通信。对于许多设备来说,中断请求线是必要的通信媒介。在初始化后,操作系统将对与其连接的每个设备启用请求线。在此工作之前,Xinu内核为许多设备启用了中断。最值得注意的是UART(通用异步接收器-发送器)和USB。UART中断允许接收器传输数据,这对于获取输入的系统函数非常有用,如getc()。但是,如果没有启用中断,用户模式函数将无法获取输入。

如图1所示,关键初始化序列可能发生在System模式。但是,当第一次从用户模式进行上下文切换时,更新CPSR中断位的msr(从寄存器传送到状态)指令未定义,这是因为如果不访问该指令,就无法在启用中断的情况下启动新线程。笔者试图通过从上下文切换例程发出svc指令来回避這个问题,随后,在更改SVC处理程序中的SPSR后,启用中断。然而,从svc返回后,系统定时器立即中断了上下文切换代码。在当前状态下,时钟处理程序(在系统定时器中断后调用)无法在用户模式下执行。最后,为了节省时间和简单便捷,不需要启动中断来实现预期目标。

本节中设置的作业涉及ARM编程和更高级的C编程,允许更多的编程自由。这样就为学生提供了一个启动到用户模式的内核,但尚未在引导加载程序中初始化Supervisor模式堆栈。他们的任务是:①建立Supervisor模式堆栈;

②实现create()的系统调用。这个功能接受可变数量的参数,使其API和调度案例写起来更有挑战性。

在学生不知道将要测试的参数数量的情况下,教师可以要求他们编写一个优雅的C实现才能获得满分。此作业的书面测试用例可能包括准备创建执行参数检查的线程。

内存保护

内存管理单元(MMU)是一个功能单元,负责监督处理器对可用物理内存的使用。因此,可以配置内存管理单元来实现内存保护,缓存是处理器之间的中介和物理内存。对于支持缓存的单元,标记为可缓存的区域相应地保存在翻译后备缓冲区(TLB)中。

处理器请求的内存地址首先由MMU检查以确保其有效。为了实现这一点,MMU检查存储在硬件寄存器中的信息,其中包含给定区域的读写权限。在确定地址可访问后,进行地址转换。这些翻译存储在TLB中,因此MMU只需引用此翻译并抓取相应的物理内存地址。对于store操作,内存系统不需要返回值。如果执行load,请求将被更新以包含位于物理地址的值,并将其发送回请求者。

树莓派3B+支持两种虚拟内存系统选项——MMU和内存保护单元(MPU)。MPU对编程区域提供更简单的接口,但由于嵌入式Xinu已经启用了MMU,因此选用MMU。这个决定更符合硬件系统教学,因为MMU是学生熟悉的必要计算机组件。

树莓派3B+定义了两级缓存——L1和L2。在默认情况下,树莓派3B+上禁用二级缓存。嵌入式Xinu最新移植初始化了MMU,但仅使用已启用的L2系统进行原子操作,从而在内核之间强制执行互斥。在此工作之前,启用的MMU并未利用其内存保护功能。

图3显示了该器件实现的存储系统。当MMU初始化时,L2缓存已启用,并且可以开始转换。如上所述,需要一个硬件寄存器来确定访问控制。在这个平台上,协处理器寄存器15(CP15)保存有关正在访问的内存区域的信息,如是否可缓存,或者是否允许当前执行模式访问它。在地址转换之后,物理地址可能驻留在两个缓存层次结构中的任何一个中,或者驻留在RAM中。该内核以虚拟和物理转换1∶1的方式配置MMU,这使得设计更加简单,其中翻译后的内存地址对请求者是可见的。该平台的内存架构允许将内存区域编程为多种固定大小之一:4KB页、64KB页、1MB节或16MB超节。最新的内核移植使用1MB部分,无子页面,以简化设计。为使代码更便于学生理解,此实现保留1MB部分。

MMU区域由转换表描述符定义,所选的1MB节大小使用第一级描述符格式。当C位设置后,1MB区域是可缓存的。当考虑外设地址空间时,该区域的C位必须禁用,否则即使有基本输出也可能会产生严重影响。描述符的12位保留用于该节的基址部分,AP位允许扩展正常访问权限(AP)位。当设置APX时,将提供两种额外的特权状态,如特权只读,而不是特权和用户访问控制权限的四种状态。本实验不设置APX位,而是使用完全访问模式或使用AP位的用户写禁用模式。域格式定义了内存区域集合的访问类型,从而使高级内核具有更大的灵活性。为简单起见,在此实现中,为整个1MB部分定义了一个域。之前的嵌入式Xinu移植将域位设置为Manager访问类型,这阻止了根据访问描述符中的权限位对访问进行检查,因此永远不会生成权限错误。因此,要实施一定程度的内存保护,不仅需要更改AP位,还要更改域位。将这些位更改为客户端模式,根据条目中的AP位检查访问。嵌入式Xinu的MMU初始化代码是用C和ARM汇编编写的。mmu_init() C函数使用辅助函数mmu_section()来监督区域的一般初始化,以设置适当的描述符格式位。一个for循环循环访问内存地址,调用helper,而一旦所有段基地址都被映射并且外设被标记为不可缓存,MMU就可以启动。ARM例程启动mmu()通过CP15执行必要的操作。首先,所有指令和数据高速缓存行都无效。在设置域和TLB基址之前,TLB会失效,以防止硬件留下无效引用重置。

在对某个区域应用受限访问权限(即用户模式只读)并且启用MMU后,中止模式成为可能的执行模式。Abort模式是内存中止时使用的异常模式。内存中止是由无效的数据内存访问引起的,如变量存在于内存地址0x00300处,并且该区域由第一级描述符定义为用户模式只读,则尝试从用户更改该处的值的行为将导致数据存储器中止。中止处理程序可以编程为以某种方式处理此类故障,具体方式取决于处理者的设计,它可能会在执行动态配置指令后再次尝试错误指令。否则,简单的中止处理程序将跳过错误指令。

在本节设计的作业中,学生将看到一个按顺序创建并运行两个线程的主程序。运行的第一个线程模拟普通线程,它进行一些系统调用,如gettid()、getcpuid(),并打印每个结果。第二个线程模拟全局变量的恶意赋值,将导致内核出现不可恢复的故障。学生的任务是防止故障发生,而无需删除或更改恶意线程的指令。

该作业包含三个主要部分:

①将insert()函数设为系统调用;

②在mmu_init()例程期间修改访问权限位;

③编写一个简单的中止模式处理程序来跳过无效指令。

全局线程就绪列表通过insert()修改,它将已就绪线程ID放入就绪列表中。将列表索引赋值为-1将导致调度程序发生故障,并打印内核错误消息,打印错误消息后不会继续执行,所以学生可以先考虑执行模式提供的保护。如果在Supervisor模式下执行insert(),那么就绪列表将只能从特权模式写入。因此,如果就绪列表的地址已知,则MMU可以配置为只允许从特权模式对该地址进行写访问。

该实现使用一种方案来挑选出就绪列表,将其放入远离内核内存的已知位置。首先,为了使就绪列表地址已知,需要进行修改。在initialize.c中,声明了就绪列表队列,可以使用编译器指令,与加载器脚本一起,将就绪列表复制到已知位置(如图4)。因为MMU使用1MB的部分进行1:1转换,就绪列表可以定义在较高的物理部分,如0x00800000。

通过可见的已知位置的就绪列表,学生可以开始修改mmu_init()以使用USER READONLY访问权限位。最初,两个AP位均被设置,允许对特权和非特权模式进行完全读写访问。修改仅需要设置第二个AP位,从而授予用户对保存就绪列表的区域进行只读访问。一旦完成,学生将注意到内核在尝试进行现在无效的分配后挂起,这不是期望的行为,描述要求跳过无效指令,因此下一部分需要一些ARM汇编。内核挂起是因为它尝试内存写入时出现错误,导致内核陷入了中止模式。学生必须修改中止处理程序以跳过出错的指令。当处理器进入中止模式时,链接寄存器被设置为中止指令的地址+8。因此,要返回到無效赋值之后的指令,中止处理程序必须从链接寄存器中减去4并跳转到该地址。

结果与展望

本文引入了系统调用,这是嵌入式操作系统的一个重大结构变化。此外,还提供了基于模式的内存保护实现,所设计的作业提出了相关理论在实践中的应用方式。通过教学实践,取得了较好的效果。

未来工作的许多方向都涉及更高层次的扩展,如可以研究嵌套SVC调用。嵌套SVC指令的能力将简化Xinu内核,特别是如果需要单独的用户和内核空间。另外,据学生反馈,他们对现代CPU的多核技术较感兴趣,因此,笔者目前正在设计启用树莓派上其他三个核心的实验材料。

参考文献:

[1]刘威,常瑞,谢耀滨.面向系统能力培养的嵌入式系统课程教学模式改革与实践[J].计算机教育,2019(01):39-43.

[2]ARM Ltd.ARM Architecture Reference Manual Armv8,for Armv8-A architecture profile[EB/OL].https://static.docs.arm.com/ddi0487/ea/DDI0487E.

[3]ARM Ltd. SVC Handlers.[EB.OL].https://infocenter.arm.com/help/index.js?topic=/com.arm.doc.dui0203j/Cacdfeci.html.

[4]Dennis Brylow. An experimental laboratory environment for teaching embedded operating systems[C].Proceedings of the 39th SIGCSE technical symposium on computer science education:192-196.

[5]Douglas Comer.Operating System Design:The Xinu Approach[M].邹恒明,周亮,曹浩,等,译.北京:机械工业出版社,2013.

[6]陈刚,关楠,吕鸣松,等.实时多核嵌入式系统研究综述[J].软件学报,2018,29(07):2152-2176.

猜你喜欢
实验教学
问题引导在初中化学实验教学中实践探索
关于基础教育阶段实验教学的几点看法
光反应与有机化学实验教学结合的研究
小议初中化学演示实验教学
电容器的实验教学
对初中化学实验教学的认识和体会
几何体在高中数学实验教学中的应用
基于云计算的计算机实验教学探讨
高中生物实验教学中形成性评价的实施——以“观察根尖分生区组织细胞的有丝分裂”实验教学为例
高中自然地理课堂实验教学的探讨