【问题标题】:How OS restricts user process from accessing kernel memory操作系统如何限制用户进程访问内核内存
【发布时间】:2013-12-31 12:54:55
【问题描述】:

在 32 位 Linux(或 windows 等)中,用户进程无法访问 内核地址空间。说 0xC0100000 (在 3:1 拆分中,例如 linux)或 0x80E00000(1:1分割如windows)。

我知道用户应用程序中的以下代码会引发分段错误。

int* a = 0xC0100000;
int b = *a;

但是,我不能 100% 确定实际原因。 我假设如果我们尝试执行上述代码,MMU 将引发 segfault,因为虚拟地址 0xC0100000 的相应页表条目具有管理位标志。 这是 100% 正确的吗?如果正确,操作系统如何阻止进程通过 TLB 缓存访问内核虚拟地址?

我也认为使用分段可以实现相同的限制。 即如果 GDT 的 DS、CS、SS ... 条目的地址限制为 0xC0000000。无论页表设置如何,访问 0xC0100000 都会从分段过程中失败。 如果我错了,请纠正我。

一些建议会很好。 提前谢谢你。

【问题讨论】:

  • 为什么 TLB 会影响这个?
  • 因为如果 TLB 命中,MMU 将不会遍历页表,这意味着它无法检查页表条目标志。
  • @daehee TLB 是页表条目的缓存,它包含相同的标志。
  • MMU 没有“segfault”,它发送一个处理器异常。该异常触发了一个由内核处理的中断,稍后可以向应用程序发送SIGSEGV 信号
  • @daehee:不,虽然 TLB 命中不会导致页面遍历是正确的,但权限也会被缓存。

标签: linux segmentation-fault kernel paging


【解决方案1】:

重要的是应用程序在user space(或用户模式)中看到的address space。内核地址空间对应用程序不可见(仅对内核可见,例如当它正在执行 system calls 时)。

当执行从用户模式切换到内核模式(例如通过系统调用或中断)时,MMU 会更改状态,以访问内核页面。细节是特定于处理器的(在 x86 和 ARM 上不同),并且根据定义对应用程序代码不可见。请参阅page fault 上的维基页面。

【讨论】:

  • 然而,在例如Linux,每个进程的虚拟地址空间被划分(PAGE_OFFSET)分为用户可以触摸的部分和只有内核可以触摸的部分。 OP 正在询问这是如何实现的。
猜你喜欢
  • 2012-03-02
  • 2021-06-04
  • 2014-05-22
  • 2020-03-12
  • 2013-06-16
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2016-10-21
相关资源
最近更新 更多