修改了两点错误 是ph.vaddr 不是php.vaddr

溢出这部分如果没有安全基础的话可能看不懂

其实是`ph.vaddr + ph.memsz`两数相加超过了64位整数的表示范围,也就是从0xffffffffffffffff重新回到0x0000000000000000,如果没有溢出检测的话,系统会认为这是一个合理的数据从而将`ph.memsz`指定的大量恶意数据直接覆盖到将来cpu会执行到的位置从而获取权限。

可以放个译者注之类的东西
This commit is contained in:
ruokeqx
2022-06-01 22:32:12 +08:00
committed by GitHub
parent e45d5a3714
commit 673b7eaa2e

View File

@@ -31,6 +31,6 @@
在准备新内存映像的过程中,如果`exec`检测到像无效程序段这样的错误,它会跳到标签`bad`,释放新映像,并返回-1。`exec`必须等待系统调用会成功后再释放旧映像:因为如果旧映像消失了,系统调用将无法返回-1。`exec`中唯一的错误情况发生在映像的创建过程中。一旦映像完成,`exec`就可以提交到新的页表(***kernel/exec.c***:113)并释放旧的页表(***kernel/exec.c***:117)。
`exec`将ELF文件中的字节加载到ELF文件指定地址的内存中。用户或进程可以将他们想要的任何地址放入ELF文件中。因此`exec`是有风险的因为ELF文件中的地址可能会意外或故意的引用内核。对一个设计拙劣的内核来说后果可能是一次崩溃甚至是内核的隔离机制被恶意破坏即安全漏洞。xv6执行许多检查来避免这些风险。例如`if(ph.vaddr + ph.memsz < ph.vaddr)`检查总和是否溢出64位整数危险在于用户可能会构造一个ELF二进制文件其中的`php. vaddr`指向用户选择的地址,而`php. memsz`足够大使总和溢出到0x1000这看起来像是一个有效的值。在xv6的旧版本中用户地址空间也包含内核但在用户模式下不可读写用户可以选择一个与内核内存相对应的地址从而将ELF二进制文件中的数据复制到内核中。在xv6的RISC-V版本中这是不可能的因为内核有自己独立的页表`loadseg`加载到进程的页表中,而不是内核的页表中。
`exec`将ELF文件中的字节加载到ELF文件指定地址的内存中。用户或进程可以将他们想要的任何地址放入ELF文件中。因此`exec`是有风险的因为ELF文件中的地址可能会意外或故意的引用内核。对一个设计拙劣的内核来说后果可能是一次崩溃甚至是内核的隔离机制被恶意破坏即安全漏洞。xv6执行许多检查来避免这些风险。例如`if(ph.vaddr + ph.memsz < ph.vaddr)`检查总和是否溢出64位整数危险在于用户可能会构造一个ELF二进制文件其中的`ph.vaddr`指向用户选择的地址,而`ph.memsz`足够大使总和溢出到0x1000这看起来像是一个有效的值。在xv6的旧版本中用户地址空间也包含内核但在用户模式下不可读写用户可以选择一个与内核内存相对应的地址从而将ELF二进制文件中的数据复制到内核中。在xv6的RISC-V版本中这是不可能的因为内核有自己独立的页表`loadseg`加载到进程的页表中,而不是内核的页表中。
内核开发人员很容易省略关键的检查而现实世界中的内核有很长一段丢失检查的历史用户程序可以利用这些检查的缺失来获得内核特权。xv6可能没有完成验证提供给内核的用户级数据的全部工作恶意用户程序可以利用这些数据来绕过xv6的隔离。
内核开发人员很容易省略关键的检查而现实世界中的内核有很长一段丢失检查的历史用户程序可以利用这些检查的缺失来获得内核特权。xv6可能没有完成验证提供给内核的用户级数据的全部工作恶意用户程序可以利用这些数据来绕过xv6的隔离。