【问题标题】:NULL pointer protection with ARM Cortex-M MPU使用 ARM Cortex-M MPU 的 NULL 指针保护
【发布时间】:2022-12-18 22:15:45
【问题描述】:

MPU in ARM Cortex-M (M0+/M3/M4/M7/etc.) 通常被宣传为允许设置防止取消引用 NULL 指针的保护。但如何在实践中做到这一点? (一些在线讨论,like in the Zephyr Project,表明这个问题不是很微不足道。)

我正在寻找在裸机 ARM Cortex-M 上以“特权模式”运行的最简单的 MPU 代码。请注意,“防止取消引用 NULL 指针”对我来说意味着防止读取和写入。此外,它不仅与地址 0x0 有关,还与它的小偏移量有关。例如,通过 NULL 指针访问结构成员也应该导致 MPU 异常:

struct foo {
    . . .
    uint8_t x;
};
. . .
uint8_t x = (*(struct foo volatile *)NULL)->x; // should fail!

【问题讨论】:

  • 实际上,您展示的是 0 的小偏移量的 ax 示例一个空指针解引用,因为你解引用了空指针第一的在访问 x 成员之前。
  • 另请注意,在许多裸机系统上,地址 0 实际上可能是一个完全有效的地址(例如,可能是 RAM 开始的地方)。
  • ARM 内核中的地址 0 可以映射到闪存、RAM 或外部存储器,因此地址 0 非常合适。您需要配置 MPU 以禁止对地址 0 的任何访问/来自地址 0 的任何访问。
  • @Some-programmer-dude:是的,绝对是,地址 0x0 是问题的一部分,也是我问题的很大一部分。在 ARM Cortex-M 中,地址 0x0 是向量表的起始位置。
  • @MiroSamek 可以是也可以不是。向量表地址可设置。根据型号的不同,您甚至可以将其存储在选项字节中并在引导期间加载。

标签: c arm embedded arm-mpu


【解决方案1】:

经过一些实验后,我提出了似乎适用于大多数 ARM Cortex-M MCU 的 MPU 设置。这是代码(使用 CMSIS):

/* Configure the MPU to prevent NULL-pointer dereferencing ... */
MPU->RBAR = 0x0U                          /* base address (NULL) */
            | MPU_RBAR_VALID_Msk          /* valid region */
            | (MPU_RBAR_REGION_Msk & 7U); /* region #7 */
MPU->RASR = (7U << MPU_RASR_SIZE_Pos)     /* 2^(7+1) region, see NOTE0 */
            | (0x0U << MPU_RASR_AP_Pos)   /* no-access region */
            | MPU_RASR_ENABLE_Msk;        /* region enable */

MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk       /* enable background region */
            | MPU_CTRL_ENABLE_Msk;        /* enable the MPU */
__ISB();
__DSB();

此代码在地址 0x0 周围设置了一个不可访问的 MPU 区域#7(任何其他 MPU 区域也可以)。这甚至适用于 MCU,其中向量表也位于地址 0x0。显然,除了 LDR/STR,MPU 不会检查对区域的访问,例如在 Cortex-M 异常进入期间读取向量地址。

但是,如果向量表位于 0,则尺寸禁止访问区域不得包含任何 CPU 可能会访问的数据合法地使用 LDR 指令读取。这意味着不可访问区域的大小应该大约是向量表的大小。在上面的代码中,大小设置为 2^(7+1)==256 字节,即使对于相对较小的向量表也应该没问题。

上面的代码也适用于自动重定位向量表的 MCU,例如 STM32。对于这些 MCU,不可访问区域的大小可以一直增加到重定位的向量表,例如 STM32 中的 0x0800'0000。 (您可以将大小设置为 2^(26+1)==0x0800'0000)。

防止空指针取消引用是提高系统健壮性甚至防止恶意攻击的重要工具。我希望这个答案能帮助嵌入式开发人员。

【讨论】:

    猜你喜欢
    • 2017-06-07
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 2015-04-20
    • 2021-10-24
    • 2015-11-29
    • 1970-01-01
    相关资源
    最近更新 更多