保护环
Multics引入的最具革命性的想法之一是保护环的概念——一种特权的分层,其中内环(环0)是最有特权的,并且外环的特权最低[41]。因此,不受信任的用户进程在外环中执行,而直接与硬件交互的受信任和特权内核在环0中执行,其他环可用于或多或少特权的系统进程。
保护环通常采用硬件支持,这是当今大多数通用处理器提供的功能,尽管保护环的数量可能有所不同。例如,霍尼韦尔6180支持多达八个环,英特尔的x86四个,ARMv7三个(加上TrustZone的额外一个)和PowerPC两个。但是,正如我们将看到的,故事变得有点混乱,因为一些现代处理器也引入了更多不同的处理器模式。现在,我们只是观察到大多数常规操作系统只使用两个环:一个用于操作系统,一个用于用户进程。
每当权限较低的代码需要需要更多权限的函数时,它就会“调用”下环以请求将此函数作为服务执行。因此,只有受信任的特权代码才能执行最敏感的指令或操作最敏感的数据。除非具有较少权限的进程诱骗更多特权的代码执行它不应该做的事情(作为困惑的副手),否则环会提供强大的保护。Multics的最初想法是,环之间的转换将通过实施严格控制和调解的特殊呼叫门进行。例如,外环中的代码不能只调用内环中的任何指令,而只能调用第一个调用的预定义入口点经过审查,看看它及其参数是否不违反任何安全策略。
虽然像x86这样的处理器仍然支持呼叫门,但很少有操作系统使用它们,因为它们相对较慢。相反,用户进程通过执行操作系统处理的软件中断(“陷阱”)或更常见的是通过特殊的高效操作来过渡到操作系统内核(“系统调用”)。系统调用指令(名称如SYSCALL,SYSENTER,SVC,SCALL等,具体取决于体系结构)。许多操作系统将系统调用的参数放在一组预定义的寄存器中。与调用门一样,陷阱和系统调用指令也确保在操作系统中的预定义地址继续执行,代码在其中检查参数,然后调用相应的系统调用函数。
除了用户进程调用操作系统外,大多数操作系统还允许内核调用用户进程。例如,基于UNIX的系统支持操作系统用来通知用户程序“有趣的事情”的信号:错误,过期的计时器,中断,来自另一个的消息工艺等如果用户进程为信号注册了一个处理程序,操作系统将停止进程的当前执行,将其所有处理器状态存储在进程堆栈上,形成所谓的信号。帧,并在信号处理程序上继续执行。当信号处理程序返回时,进程执行sigreturn系统调用,使操作系统接管,还原堆栈上的处理器状态并继续执行进程。
安全域(如操作系统内核和用户空间进程)之间的边界是检查系统调用本身及其安全性参数的好地方违反。例如,在基于功能的操作系统中,内核将验证功能,而在MINIX3等操作系统中,只允许特定进程进行特定调用,因此任何尝试拨打不在预先批准列表中的呼叫将被标记为违规。同样,基于Windows和UNIX的操作系统必须检查许多系统调用的参数。例如,考虑常见的读写系统调用,通过这些调用,用户请求将数据从文件或套接字读取到缓冲区中,或者从缓冲区分别到文件或套接字中。在执行此操作之前,操作系统应检查要写入或读取的内存是否实际归进程所有。
执行系统调用后,操作系统将控制权返回给进程。在这里,操作系统还必须注意不要返回危及系统安全性的结果。例如,如果一个进程使用mmap系统调用来请求操作系统将更多内存映射到其地址空间,则操作系统应确保它返回的内存页不再包含来自另一个进程的敏感数据(例如,首先将每个字节初始化为零).
零初始化问题可能非常微妙。例如,编译器经常在数据结构中引入填充字节以对齐。由于这些填充字节在编程语言级别根本不可见,因此编译器可能认为没有理由将它们初始化为零。但是,当操作系统返回此类数据结构以响应系统调用并且单元化填充包含来自内核或其他进程的敏感数据时,就会发生安全违规。
顺便说一下,即使是我们前面提到的UNIX系统中的信令子系统也是一个有趣的安全案例。回想一下,sigreturn采用堆栈上的任何处理器状态并恢复该状态。现在假设攻击者能够破坏进程的堆栈并在堆栈上存储虚假信号帧。如果攻击者也能够触发sigreturn,他们可以一举设置整个处理器状态(包括所有寄存器值)。这样做在熟练的攻击者手中提供了一个强大的基元,被称为Sigreturn导向编程(SROP)。
如前所述,如今有关保护环的情况稍微令人困惑,因为最近的CPU为虚拟机管理程序提供了虚拟化指令,允许它们控制硬件在环0处访问。为此,他们添加了乍一看看起来像底部额外戒指的东西。由于在x86处理器上,术语“ring0”已成为“操作系统内核”的同义词(以及“环”与“用户进程”的同义词),因此这种新的虚拟机管理程序环通常称为“ring–1”。它还指示其各自虚拟机中的操作系统可以继续在本地执行环0指令。然而,严格来说,它的目的与原始戒指大不相同,虽然环-1这个名字已经卡住了,但它可能有点像用词不当。
为了完整起见,我们应该提到事情可能会变得更加复杂,因为一些现代处理器仍然具有其他模式。例如,x86提供所谓的系统管理模式(SMM)。当系统启动时,固件控制硬件,并为操作系统接管系统做好准备。但是,启用SMM后,固件会在向CPU发送特定中断时重新获得控制权。例如,固件可以指示每当按下电源按钮时它都希望接收中断。在这种情况下,常规执行将停止,固件将接管。例如,它可以保存处理器状态,执行任何需要执行的操作,然后恢复操作系统以进行有序关闭。在某种程度上,SMM有时被视为比其他环(环-2)低的水平。
最后,英特尔甚至以英特尔管理引擎(ME)的形式增加了环-3。ME是一个完全自主的系统,现在几乎存在于英特尔的所有芯片组中;它在单独的微处理器上运行一个秘密且完全独立的固件,并且始终处于活动状态:在启动过程中,当机器运行时,当它处于睡眠状态时,即使断电。只要计算机连接到电源,就可以通过网络与ME通信,例如安装更新。虽然非常强大,但它的功能在很大程度上是未知的,除了它运行自己的小型操作系统11,研究人员发现其中包含漏洞。主CPU附带的附加处理器(无论是ME还是Apple的T2和Google的Titan芯片等相关处理器)都提出了一个有趣的一点:在主CPU上运行的操作系统是否能够满足当今的安全要求?至少,这种趋势似乎通过专用系统(硬件和软件)来增强它的安全性。
低端设备和物联网
上述许多功能都可以在大多数通用处理器体系结构中找到。然而,在物联网或一般的嵌入式系统中不一定如此,并且通常使用定制的操作系统。简单的微控制器通常没有MMU,有时甚至没有MPU、保护环或我们在常见操作系统中依赖的任何高级功能。系统通常很小(减少攻击面),应用程序受信任(并可能经过验证)。然而,设备的嵌入式性质使得很难检查甚至测试其安全性,并且无论它们在安全敏感活动中发挥作用的何处,安全性隔离/遏制和调解的手段应由环境在外部强制执行。更广泛的物联网问题在网络物理系统安全CyBOK知识领域得到解决。