Max Kellermann,CM4all(一家德国网络托管公司)的开发人员,在2022年初发现了这个问题,但并非通过漏洞检查。他在调试时得知客户对服务器日志自发损坏感到不满。
Kellermann花了数月时间追踪它。他的工作最终引导他深入探索Linux内核处理管道和页面缓存的方式。他意识到,他找到的解释日志损坏的bug实际上要严重得多——一个完整的权限提升漏洞(完整的权限提升漏洞是一种严重的安全缺陷,允许拥有低级访问权限的攻击者——如标准用户、访客或无特权的应用程序——获得对系统的管理员、超级用户或根级别控制。这意味着攻击者绕过了所有预期的安全边界,赋予他们完全控制权,以修改系统文件、安装软件、窃取数据或删除文件)。
他负责任地向Linux内核团队和Linus Torvalds本人披露了该漏洞。几天之内就打了补丁。
真正的问题是——当splice()将数据传输到管道时,它忘记清除目标缓冲区上的这个标志。因此,splice处理后的页面(直接指向文件的只读页面缓存)仍然设置了CAN_MERGE。 现在,如果你向该管道写入,内核看到CAN_MERGE,假设该页面可写,并直接将你的数据合并到页面缓存中——即文件的内存内容——而不进行任何权限检查。 结果:你可以覆盖任何你有读取权限的文件的内容,包括SUID(设置用户ID)的root二进制文件,如su、passwd、sudo。
为什么这个bug如此重要? 几个原因: