内存权限:操作系统如何守护你的安全门禁

文章摘要

手机内存权限管理就像大楼门禁系统:内存是房间,mmap用于申请新房间权限(R/W/X),mprotect用于修改现有权限。操作系统严格审核权限变更,防止恶意代码执行(如禁止同时拥有W+X权限)。iOS限制更严,普通APP无法获得可写又可执行的内存权限,只有特殊应用(如Safari)才允许。这种机制保障了系统安全和稳定,避免数据被篡改或意外执行。


1. 比喻:房间和门禁卡

想象你的手机是一座大楼,内存就是这座大楼里的许多房间。每个房间都可以用来存放不同的东西(数据、代码等)。

1.1 房间的门禁卡

每个房间的门上都有一个门禁卡系统,门禁卡上写着你能在这个房间里做什么:

  • R(Read)读权限:你可以进房间看里面的东西。
  • W(Write)写权限:你可以在房间里动手改东西、添东西。
  • X(Execute)执行权限:你可以在房间里“表演节目”,也就是让里面的内容变成可以运行的指令。

2. mmap 和 mprotect 的作用

2.1 mmap:开新房间

  • 当你用 mmap,就像是在大楼里新开了一个房间,并且告诉门禁系统:“我要一个能读、能写、能执行的房间”。
  • 操作系统会根据你的要求,给你一张门禁卡(内存页权限),但会严格检查你有没有资格要这些权限。

2.2 mprotect:换门禁卡

  • 有时候你已经有了房间,但想换一张门禁卡,比如原来只能读,现在想加上写权限,或者加上执行权限。
  • 这时你用 mprotect,请求操作系统帮你换卡。
  • 操作系统会再次检查你有没有资格换卡,尤其是加上“执行”权限时会特别严格。

3. 为什么要这么做?

  • 安全:如果每个人都能随便进房间、改东西、表演节目,坏人就能偷偷在房间里藏炸弹(恶意代码)。
  • 稳定:防止程序自己不小心把数据当成代码执行,导致崩溃。

4. 现实中的例子

  • 代码房间(.text 段):只能读和执行,不能写。这样别人就不能偷偷改你的表演内容。
  • 数据房间(堆、栈):只能读和写,不能执行。这样别人就不能把数据当成表演内容来执行。

5. iOS 的特殊规定

  • iOS 这座大楼的保安特别严格,普通人(App)永远不能要“能写又能执行”的门禁卡,防止有人偷偷在房间里排练危险节目(JIT、恶意代码)。
  • 只有经过特殊审批(比如 Safari 的 JS 引擎)才有资格要这种门禁卡,而且保安会全程盯着。

6. 总结

  • mmap:开新房间,申请门禁卡。
  • mprotect:换门禁卡,改房间权限。
  • R/W/X 权限:决定你能不能看、改、执行房间里的内容。
  • 操作系统:像大楼保安一样,严格审核每一次门禁卡的申请和更换,保障大楼安全。

我们来用“门禁卡”这个比喻,深入到硬件(MMU)层面,看看内存页权限是怎么设置和生效的。


1. 门禁卡在硬件里的真实身份:页表(Page Table)

在计算机里,每一块内存房间(内存页)门口都挂着一张门禁卡,这张卡其实就是页表项(Page Table Entry, PTE)

  • 页表是一个大表,记录了每一页内存的各种权限和属性。
  • 每个进程有自己的页表,操作系统(iOS内核)负责管理。

2. MMU:门禁卡的“刷卡机”

  • **MMU(内存管理单元)**就像大楼的刷卡机,每次CPU要访问内存时,MMU都会查一下对应页表项,看看你有没有权限。
  • MMU是硬件,速度极快,无法被普通程序绕过。

3. 页表项里都写了什么?

以**ARM64(AArch64)**为例,每个页表项里有很多“开关”,最关键的有:

  • AP(Access Permissions):读/写权限
  • UXN(Unprivileged eXecute Never):普通程序能不能执行
  • PXN(Privileged eXecute Never):内核能不能执行
  • RW(Read/Write):能不能写
  • RO(Read Only):只读

形象点说:

权限位 比喻 作用
RW 门禁卡能开门写字 允许写入
RO 门禁卡只能看不能写 只读
UXN 普通员工不能在这开会 普通程序不能执行
PXN 管理员也不能在这开会 内核不能执行

4. 设置流程(以iOS为例)

  1. App请求分配内存(比如mmap/mprotect)
  2. iOS内核检查权限,决定这块内存的用途(数据/代码/只读/可执行)
  3. 内核修改页表项,设置好RW/RO/UXN/PXN等位
  4. MMU自动生效,CPU每次访问内存都要“刷卡”,不符合权限就报警(触发异常)

5. 例子:分配一块只读、不可执行的内存

  • 页表项设置:RW=0, RO=1, UXN=1, PXN=1
  • 结果:只能读,不能写,不能执行

6. 例子:分配一块可执行的代码段

  • 页表项设置:RW=0, RO=1, UXN=0, PXN=0
  • 结果:只读,但可以执行

7. 违规会怎样?

  • 如果App试图在UXN=1的页上执行代码,MMU会立刻发出“执行权限异常”,操作系统会终止进程。
  • 如果试图写只读页,也会触发“写保护异常”。

8. 总结

  • 门禁卡=页表项,由内核设置,硬件MMU严格执行
  • 权限位=门禁卡权限,包括读、写、执行
  • MMU=刷卡机,每次访问都要查权限,违规就报警
  • 这套机制让iOS的内存保护非常坚固,软件无法绕过

你可能感兴趣的:(操作系统,安全)