bsd/kern/sys_coalition.c 中的 sysctl_coalition_get_pid_list 函数使用 coalition_get_pid_list 函数收集一个联盟中的 PID 列表。该函数在成功时返回 PID 数量,失败时返回负的 errno。然而,sysctl_coalition_get_pid_list 函数没有正确检查错误条件,这意味着它会尝试通过 SYSCTL_OUT 向用户空间发送负数个 PID。由于长度参数是 size_t 类型,最终导致调用 copyout 时传入一个非常大的值。
起初我认为这会是一个内核信息泄露漏洞,因为内核会尝试从栈复制数据到用户空间缓冲区,但最终遇到未映射的页面并中止复制。然而,SYSCTL_OUT 不会复制部分值,而且在 macOS 上,如果地址加上大小发生回绕,copyio 会提前中止。这使得该漏洞在 macOS 上无法利用。
但在 iOS(至少是 iOS 10.1.1)上,如果地址加上大小发生回绕,copyio 函数会触发内核恐慌。这意味着该漏洞可用于拒绝服务攻击。
利用需要 root 权限。
我于 2017 年 9 月 21 日向 Apple 报告了此问题。它被分配了 CVE-2017-13833 CVE-2017-7173。Apple 在 macOS 10.13.2 和 iOS 11.2 中修复了该问题。
(Apple 后来发现 CVE-2017-13833 之前已分配给另一个不同的问题,因此将本问题重新分配为 CVE-2017-7173。)
sysctl_coalition_get_pid_list-dos 的代码已发布到公共领域。出于礼貌,如果您引用或使用了任何这些代码,我要求您注明出处。