内存安全 - 地址空间布局随机化(ASLR)

说明

  • 学过编译原理可知,C语言程序中所有变量的内存地址编译后都是确定了的,但是在linux平台上实际使用时可以发现变量的内存地址并不是固定的,如下:
* 示例代码
#include 

int main(){
    int a;
    
    printf("%p\n", &a);
    return 0;
}
* 运行结果
xxx@Lenovo-V110-15IKB:~/$ ./test
0x7ffdd2ec0124
xxx@Lenovo-V110-15IKB:~/$ ./test
0x7ffc577a9644
xxx@Lenovo-V110-15IKB:~/$ ./test
0x7fffef5827e4
xxx@Lenovo-V110-15IKB:~/$ ./test
0x7fff44595414
xxx@Lenovo-V110-15IKB:~/$ ./test
0x7fffe93e1964

理解

  • 程序都是在运行阶段分配内存,所有变量的逻辑地址都是在编译后就确定了,但都是相对的偏移地址,只不过全局变量是相对数据段的偏移,局部变量是相对程序栈顶的偏移。
  • 变量地址会发生变化是因为ASLR机制导致了内存段地址发生了变化。

ASLR

  • 地址空间布局随机化(ASLR)可以帮助克服某些类型的缓冲区溢出攻击,ASLR可以将基数,库,堆和堆栈放在进程地址空间中的任意随机位置,这使攻击程序很难预测下一条指令的内存地址。
  • ASLR内置在Linux内核中,并由参数控制 /proc/sys/kernel/randomize_va_space,该 randomize_va_space参数可以采用以下值:
0 : 禁用ASLR。如果使用norandmapsboot参数引导内核,则将应用此设置。
1 : 随机化堆栈,虚拟动态共享对象(VDSO)页面和共享内存区域的位置。数据段的基地址位于可执行代码段的结尾之后。
2 : 随机化堆栈,VDSO页,共享内存区域和数据段的位置。这是默认设置。
  • 设置
echo 0 > /proc/sys/kernel/randomize_va_space
* 注意:非root用户如下设置会报错
sudo echo 0 > /proc/sys/kernel/randomize_va_space
bash: /proc/sys/kernel/randomize_va_space: Permission denied
* 因为这样写系统会认为是sudo 命令重定向,而sudo命令不支持重定向,正确写法: 
sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
  • 关闭ASLR后,测试发现变量的地址就是固定的。

你可能感兴趣的:(#,Linux,内核知识)