2016-02-25 16 views
3

我读过Linux中的进程描述符(在x86上)存储在内核数据段中,但在PAGE_OFFSET(即用户地址空间)下面的地址中。由于内核数据段和用户数据段都覆盖了全部4GB地址空间,因此如果其用户代码知道其地址,则可能通过用户数据段访问进程描述符。这是否正确?如果是这样,它不是安全漏洞吗?linux进程描述符存放在哪里,什么可以访问它?

一个相关的问题:有一个断言,进程描述符的线性地址可以作为唯一的进程ID。但是,由于使用页表转换线性地址并且PAGE_OFFSET下的地址的每个进程的页表都不相同,那么两个进程是否不能将它们的进程描述符存储在相同的线性地址?

+1

你从哪里读到的?我在http://www.informit.com/articles/article.aspx?p=368650 – Barmar

+0

上看不到任何有关用户空间中的进程描述符的信息。在这里看不到任何类似的内容:http:// www .inf.fu-berlin.de/lehre/SS01/OS/Lectures/Lecture05.pdf – Barmar

+0

unix.stackexchange.com将是这个问题的更好地方。 – Barmar

回答

4

在linux中,“进程描述符”是struct task_struct [和其他一些]。这些存储在用户空间中的内核地址空间[以上PAGE_OFFSET]和而不是

这与32位内核更为相关,其中PAGE_OFFSET设置为0xc0000000。

在一个32位的内核,一个用户进程的虚拟地址空间被限制在PAGE_OFFSET

64个内核有些不同,限位并不重要一样多。 PAGE_OFFSET是0xffff880000000000

此外,内核有自己的单个地址空间映射。

每个进程/线程都有自己的虚拟地址空间,禁止用于.so库的共享内存和线程的共享内存是唯一的。它不是而是映射到内核地址空间中的任何东西。

即使有[如果有]公共地址空间映射,内核页面也会被用户进程读/写保护。


一个相关的问题:

这实际上是两个问题

有一个论断,即进程描述符的线性地址可以作为一个独特的进程ID。

不可以这样可以不是有几个原因。

只有内核有权访问(即“知道”)地址。其次,如果一个进程终止,它是一个僵尸,直到父进程通过wait“收获”它。内核必须记住哪些进程是僵尸(即它们的pids而不是将被重新用于新进程),直到父节点获得它们。但是,

task_struct是相当大的。因此,当进程进入僵尸时,内核抓取task_struct数据的一部分(例如pidstatus),并将它们保存在“僵尸”结构中。内核几乎可以立即重用task_struct [使用不同的 pid]。

例如,虽然用PID 37的过程可以在地址有一个任务结构(如)为0x1000它运行时,终止后,但在此之前收获,PID 37 没有任务结构地址和任务结构位于0x1000可能已经被指定为PID 23727

然而,由于线性地址开始使用页表转换,并且页表是针对以下PAGE_OFFSET地址每一个过程的不同,则不能两个进程的存储过程描述符在相同的线性地址?

再一次没有。

+0

感谢您的回答。我认为你是对的,但你能否回顾我上面的评论,并帮助澄清混淆?其次,有没有关于内核的最新书籍可以覆盖例如x86-64内存管理?我发现的唯一一本书太旧了:[2005年出版](http://www.amazon.co.uk/Understanding-Linux-Kernel-Daniel-Plerre/dp/0596005652)。 – snoopy

相关问题