引入一种新的机制来检测和减轻基于MCU的应用中的存储器损坏。
在实时操作系统(RTOS)级别工作的嵌入式软件开发人员知道,内存损坏问题很容易引入,很难检测,并且通常会破坏应用程序的安全性。这使得防止这些问题成为行业标准、测试工具和RTOS解决方案提供商的热门话题。尽管如此,在减轻微控制器单元(MCU)设备上的存储器损坏方面仍然存在显著的限制,因为它们不能支持更复杂的编程和RTOS技术。
作为全球数十亿应用的核心,MCU带来了独特的安全和安保挑战。由于没有内存管理单元(MMU)或内存保护单元(MPU ),并且几乎没有能力在代码中包含内存保护功能,MCU为嵌入式开发人员提供了很少的选项来确保他们系统的健壮性。
随着MCU部署的不断增加并支持更多连接的系统,开发人员需要更好的方法来防止存储器损坏问题,同时又不影响这些硬实时系统的严格功能和性能要求。
基于MCU的应用面临的安全挑战
为了最大限度地减少处理器工作负载和内存占用,基于MCU的应用程序倾向于在所有线程之间全局共享的单个地址空间内运行。与运行在更高级别的RTOS(如嵌入式Linux)上的应用不同,后者将内存划分为不同的地址空间,MCU应用可以访问整个范围的内存。这种单一的方法让开发人员不得不寻找自己的方法来防止应用程序函数破坏自己段外的内存。
当内存位置中的数据通过意外或不希望的方式被更改时,例如将指针从有效地址更改为可疑地址,就会发生损坏。例如,函数指针的损坏可能导致程序执行跳转到无效的内存位置,从而导致系统故障。如果黑客怀疑这一弱点存在,他们可以利用未受保护的指针将执行误导到他们通过称为代码注入的技术引入的恶意代码。
防止内存损坏需要远见和知识。开发人员需要认识到什么时候可能会出现问题(在多线程访问相同内存位置的应用程序中,这并不容易),并知道如何最小化出现问题的可能性。以下是针对没有内置内存保护的设备的一些典型补救策略:
l 空指针检查确保引用在使用时指向有效的内存位置。
l 使用校验和或CRC来检测和处理潜在的不安全内存访问。
l 将值与存储在不同存储位置的数据进行比较,看它们是否匹配。
这些技术消耗设备资源,并且依赖于开发人员记住在哪里使用它们。后两者在规划、架构和测试方面也需要相当大的努力。
PX5 RTOS专为要求苛刻的基于MCU的应用而设计,提供内置的内存保护方法,最大限度地减少开发人员和设备的开销。这种方法被称为指针数据验证(PDV)。
用PDV减轻内存损坏
PDV是PX5 RTOS独有的一种简单而强大的内存地址验证方法。PDV专为无法访问MMU或MPU的资源受限的MCU应用而设计,是一种纯软件技术,它为存储器结构创建并存储唯一的验证码,以帮助应用避免意外和未经授权的访问。
一旦开发人员打开PDV,PX5 RTOS会在将值加载到敏感数据位置时自动创建验证码。在应用程序使用敏感数据之前,RTOS会再次生成验证码,并将其与存储的值进行比较。如果这两个代码不匹配,PX5 RTOS会调用一个中央错误处理函数来执行开发人员指定的操作。
开发人员可以定义生成验证码的公式,或者使用PX5 RTOS提供的默认机制。默认验证码是传递给RTOS的秘密运行时标识(例如来自真随机数生成器的结果)、敏感数据的值以及存储生成代码的地址的组合。默认公式如下:Verification Code = ((Data Value) + (Address to Store Code) + (Secret)) ^ (Secret)
开发者如何使用PDV
开发人员如何使用PDV保护敏感数据结构的一个例子是函数指针验证(FPV)。当使用PX5 RTOS构建应用程序时,开发人员可以使用PX5 _ FUNCTION _ POINTER _ VERIFY _ ENABLE标志来确保在使用之前验证所有函数指针。以使用PX5 RTOS支持的POSIX线程(pthreads) API创建应用程序的启动例程函数指针为例:
假设编译器按照表1中指定的方式分配内存。让我们进一步说明,entry_routine函数指针的计算验证码是0x9D919C7D。图1显示了线程创建后的线程控制块,包括原始内存格式和数据观察。
在运行时使用start_routine()函数指针时,PX5 RTOS会重新计算验证码,并将其与存储的验证码0x9D919C7D进行比较。如果新计算的代码与存储的代码匹配,则认为函数指针有效,并调用函数start_routine()。如果代码不匹配,函数指针或存储的验证码中很可能存在内存损坏,因此PX5 RTOS调用中央错误处理函数。
通过这种方法,试图远程改变程序执行的黑客将会失败,因为他们注入的代码不能生成匹配的验证码。
从根本上防止内存损坏
PDV是一项正在申请专利的技术,它为开发人员提供了强大的内存损坏检测和缓解功能,而不会影响应用性能或资源预算。PX5 RTOS本身是超小型的(最少使用时不到1 KB),超便携的(具有完全兼容的pthreads API),并且经过严格测试(每个版本都有100%的C语句和分支决策覆盖),这使它成为需要可靠确定性、安全性和安全性的系统的理想基础。
虽然PDV是为没有存储器保护硬件的MCU环境设计的,但是它也可以为具有MPU和/或MMU功能的更健壮的处理器补充代码安全和安全实践。