针对CVE-2023-6931的内核恐慌PoC
CVE-2023-6931是perf_event中的一个漏洞,由组中read_size的整数溢出导致堆缓冲区溢出。
perf_events是Linux内核提供的一个性能监控和分析框架。该框架能够跟踪硬件和软件组件产生的各种性能相关数据。
perf_event_open系统调用/proc/sys/kernel/perf_event_paranoid的值必须为1或更低。ulimit -n命令检查和修改。CONFIG_PERF_EVENTS。该漏洞源于read_size的整数溢出。函数perf_event_validate_size对read_size进行验证。然而,read_size的验证方式仅检查当前事件的read_size。
关键点是每次验证时,只验证当前事件,而不验证之前的事件。如果为组领导设置了PERF_FORMAT_GROUP,那么简单地添加当前事件就会增加组领导的read_size。
这最终在perf_read_group中导致问题。event->read_size的计算基于组领导的read_format,乘以nr_siblings。由于read_size变量是一个2字节的u16,它能容纳的最大值是0xffff。
为了利用此漏洞,攻击者首先创建一个设置了所有可能read_format选项的组领导事件。接着,创建大量兄弟事件。这些兄弟事件仅在read_format中设置PERF_FORMAT_TOTAL_TIME_RUNNING,以确保在perf_event_validate_size中不会出现验证问题。结果,nr_siblings变得非常大,但由于每个兄弟事件都能单独通过验证,在此阶段没有问题。
在此状态下调用perf_read_group时,由于设置了PERF_FORMAT_GROUP,组领导的read_size会持续增长。最终,这导致整数溢出,kzalloc分配了一个非常小的缓冲区。然而,由于实际事件数量很大,发生堆缓冲区溢出,导致内核恐慌。