作者:启明星辰ADLab
近日,启明星辰ADLab在对 Linux 内核进行源码审计时发现,Linux 内核的音频子系统存在一个条件竞争漏洞 CVE-2017-15265(CNVD-2017-30251、CNNVD-201710-230),条件竞争导致了 use-after-free 漏洞,可以用来进行本地提权。由于绝大部分 Linux 发行版采用了这个子系统,所以内核版本低于4.14-rc5的系统均会受到此漏洞影响,其影响范围十分广泛。启明星辰ADLab发现此漏洞后,第一时间报告给了 Linux 官方,Linux 内核创始人 Linus Torvalds 亲自进行了回复。目前,Linux 官方已给出修复方案,提醒广大用户及时采取修复措施。本文我们将详细分析此漏洞的细节及发现过程。
Linux 整体的框架图如下:
普通用户运行在用户空间,用户空间的权限有限,如果需要其他操作就需要通过一些接口进入内核空间。内核空间权限比较大,如果内核空间的代码有漏洞可进行代码执行的话,就会造成普通用户以内核权限执行代码进行提权。用户空间进入内核空间的接口有很多,如 syscall、proc、sysfs、netlink、mmap、信号、驱动文件等等,这里音频子系统是通过驱动文件的方式与用户空间进行交互的。
Linux 驱动程序一般会在/dev
目录下创建一些文件,用户可以打开这些文件,通过 ioctl 函数与内核进行交互。其中,音频子系统创建的文件在/dev/snd
目录下,如下图:
Seq 文件是此漏洞关注的目标。进入内核源码中,查看 seq 文件的 ioctl 函数,发现其有很多操作:
可以看出,这里有很多相反的操作,例如创建端口(snd_seq_ioctl_create_port
)和删除端口(snd_seq_ioctl_delete_port
),创建队列(snd_seq_ioctl_create_queue
)和删除队列(snd_seq_ioctl_delete_queue
)等。熟悉浏览器漏洞的研究人员应该知道,相反的操作可能会引发 UAF 漏洞,所以我们重点从此处入手展开分析。
通过对攻击面和攻击向量的分析,我们针对这几个相反的操作写了一个 fuzz,让其中一个线程不停地创建端口,另一个线程不停地删除端口。fuzz 后发现果然存在有漏洞,漏洞出现在snd_seq_ioctl_create_port
函数中,下图是 Linux 捕获到的 crash 信息:
对 crash 信息进行详细的分析后发现,这是一个 UAF 漏洞。漏洞函数snd_seq_ioctl_create_port
如下:
crash信息报告的是snd_seq_ioctl_create_port()
函数底部的这一句:snd_seq_set_port_info(port,&info);
。
漏洞触发的具体过程如下:
snd_seq_ioctl_create_port()
调用snd_seq_create_port()
创建了 port 这个结构体,然后切换到第二个线程;snd_seq_ioctl_delete_port()
释放了第一个线程创建的 port 后,再切换回第一个线程;snd_seq_ioctl_create_port()
继续使用了第二个线程中已释放的 port,这样就造成了 use-after-free 漏洞。分析清楚漏洞的成因之后,漏洞的修复方案也就比较清晰,其可行的修复方案有:
目前,Linux 官方已给出修复方案,该方案采用了为 port 结构体增加引用计数的方式,参考链接为:http://mailman.alsa-project.org/pipermail/alsa-devel/2017-October/126292.html
Linux 内核漏洞的影响范围十分广泛,几乎所有的 Linux 发行版都会受到影响。另外,条件竞争的漏洞也比较难通过传统的 fuzz 去发现,而且程序员也很难注意到这样的细节,所以条件竞争漏洞仍大量存在,大家应引起足够的重视。最后,启明星辰ADLab再次提醒广大用户及时进行漏洞修复,以免造成不必要的损失。
启明星辰积极防御实验室(ADLab)
ADLab成立于1999年,是中国安全行业最早成立的攻防技术研究实验室之一,微软MAPP计划核心成员。截止目前,ADLab通过CVE发布Windows、Linux、Unix等操作系统安全或软件漏洞近400个,持续保持国际网络安全领域一流水准。实验室研究方向涵盖操作系统与应用系统安全研究、移动智能终端安全研究、物联网智能设备安全研究、Web安全研究、工控系统安全研究、云安全研究。研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。