Linux内核学习--漏洞安全/虚拟内存
一、CPU熔断/幽灵漏洞解决方案
1、侧信道攻击
是密码学常见暴力攻击技术(针对加密电子设备在运行过程当中的时间消耗、功率消耗或电磁辐射之类侧信道信息泄露而对加密设备进行攻击的方法)。
有一段实现高速缓存侧信道攻击伪代码,也是熔断漏洞攻击的伪代码。set_signal();
高速缓存侧信道攻击中破解数据的流程如下:

2、CPU熔断漏洞分析
A、乱序执行、异常处理、地址空间
乱序执行: 目前CPU为提高性能,实现乱序技术。算法核心实现一个叫寄存器重命名的硬件单元来消除寄存器数据流之间的依赖关系,从而实现指令的并行执行。乱序执行的流水线有两个作用:一是消除指令之间的寄存器读后写(WAR)相关和写后(WAW)相关;二是当指令执行发生例外或者转移指令猜测错误而取消后面的指令时,可用来保证现场的精确。
从CPU角度看,指令顺序发车,乱序超车,顺序归队。
异常处理: CPU在执行过程当中可能会产生异常,但是处理器是支持乱序执行的,若异常指令后面的指令都已经执行,那么此时如何处理?
地址空间: 分页机制保证每个进程的地址空间的隔离性。分页机制也实现从虚拟地址到物理地址的转换,这个通过需要查询页表,页表可以是多级页表。每个进程都有自己的虚拟地址空间, 并且映射的物理地址是不一样的, 所以每一个进程都有自己的页表。
3、 解决方案: KPTI技术
KPTI基本思想: 把每个进程使用的一张页表分隔成两张->内核页表和用户页表。
ARM64的KPTI方案大致和x86_64的KPTI方案相似,主要体现上有所不同:
新增一个CONFIG_UNMAP_KERNEL_AT_EL0宏来打开KPTI方案,编译内核时需要打开这个选项同并重新编译内核。
原来内核空间的TLB设置为全局类型的TLB,现在把每人内核页表设置成进程独有类型的TLB,即为内核页表也分配ASID。
4、CPU“幽灵”漏洞
它和熔断漏洞相似,都利用高性能处理器的一些副作用进行高级缓存侧信道攻击。CPU“幽灵"漏洞有两个变体: 变体1 (绕过边界检查漏洞),变体2 (分支预测注入漏洞)。
一般处理器会实现动态分支预测的硬件单元, ARM的Cortex-A系列的处理器实现全局历史缓冲区(GHB),支持目标缓冲器(BTB) 和返回栈缓冲器单元(RSB)。
分支方向的预测:计数器用来表示跳转的结果,标记用来索引该表,它是指令PC值的一部分。
直接跳转的预测
间接跳转的预测
新增内存屏障指令/内核的array_index_nospec()函数/gcc的修复方案。
二、PAS/mm_ struct详解
malloc()是用户态常用的分配内存接口的函数,mmap()是用户态常用的用于建立文件映射或匿名映射的函数。
进程地址空间在内核中使用struct vm_area_struct数据结构描述, 简称VMA,也被称为进程地址空间或进程线性区。
1、进程地址空间PAS (Process Address Space)
指进程可寻址的虚拟地址空间。内存区域包含:代码段映射、数据段映射、用户进程的栈、MMAP映射区域、堆映射区域。
2、内存描述符(struct mm_struct)
Linux内核需要管理每个进程所有的内存区域以及它们对应的页表映射,所以必须抽象出一个数据结构,此数据结构就是struct mm_ struct。 进程的进程控制块(PCB) 数据结构struct task_struct中有一个指针mm指向这个mm_struct数据结构。


三、VMA/malloc系统调用
每个VMA都要连接到mm_struct中的链表和红黑树中,主要方便查找,mmap形成一个单向链表,进程中所有的VMA都链接到这个链表中,链表头是mm_ struct->mmap; mm_rb是红黑树的根节点,每个进程有一棵VMA的红黑树。
malloc函数是C语 言中内存分配函数(系统调用),mmap/munmap接口函数是用户空间最常用的两个系统调用接口。是在用户程序中分配内存、读写大文件、链接动态库文件,还是多进程间共享内存。