内存写保护共享库

时间:2013-12-31 12:06:11

标签: linux windows shared-libraries libc

我突然对某事感到好奇。 共享库如glibc(在Linux中),kernel32.dll(在Windows中)在进程之间是物理共享的。但是,由于这些库位于(映射)在用户虚拟内存地址空间中,我认为恶意进程可能会将共享库内存区域的访问属性更改为启用写入,并且会破坏每个内容以使共享它们的所有其他进程崩溃。

我在Linux中进行了以下实验,系统没有崩溃。 下面是我的测试源代码。

meltdown@ubuntu:/tmp$ cat a.c
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
int g=0;
int main(int argc, char* argv[]){
    int* a = (int*)strtoul(argv[1], 0, 16);
    printf("globals : %p\n", &g);
    printf("a : %p\n", a);
    mprotect( a, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC);

int i=0;
for(i=0; i<0x3f0; i++){
    *(a+i)=0;
}

printf("done?\n");

while(1);
return 0;
}
meltdown@ubuntu:/tmp$ 

在我运行此程序之前。我找到了libc.so.6的虚拟地址 (我设置我的内核不使用ASLR)

meltdown@ubuntu:/tmp$ ldd a
linux-gate.so.1 =>  (0xb7fff000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e37000)
/lib/ld-linux.so.2 (0x80000000)

在确认libc的地址后,我试图用NULL的

覆盖它们的某些部分
meltdown@ubuntu:/tmp$ ./a 0xb7e37000
globals : 0x804a030
a : 0xb7e37000
done?
^C
meltdown@ubuntu:/tmp$ 

由于libc是在物理内存中共享的,我假设如果我成功覆盖了libc的内存,系统就会崩溃。但是,系统很好。 我认为这里发生了一些事情,以防止我的意图。

有人可以解释一下为什么系统没有崩溃吗? 提前谢谢你。

PS。我不是在谈论NX或DEP。请不要混淆。我说的是用完全访问权限覆盖共享库内存区域(比如root进程使用mprotect(...,...,PROT_READ | PROT_WRITE | PROT_EXEC)......

1 个答案:

答案 0 :(得分:3)

  

glibc(在Linux中),kernel32.dll(在Windows中)等共享库在进程之间是物理共享的。

正确,但使用COW(写入时复制)属性。一旦您的进程写入共享页面,它就会获得不再与任何其他进程共享的页面副本。

  

我认为恶意进程可能会弄乱所有内容,导致所有其他共享进程崩溃。

不,它不能。它只能弄乱自己副本的内容并自行崩溃。