CVE-2023-53685CVE-2023-53685是Linux内核TUN(网络隧道)驱动程序中的一个内存泄漏漏洞。该漏洞由syzkaller模糊测试工具发现,存在于TUN设备的NAPI(New API)队列管理逻辑中。当用户态程序在TUN设备上同时启用NAPI和IFF_MULTI_QUEUE多队列特性后,如果通过ioctl的TUNSETQUEUE命令携带IFF_DETACH_QUEUE标志分离了某个队列,在该分离队列关闭过程中可能出现sk(socket)和skb(socket buffer)对象未被正确释放的问题,导致内核内存泄漏。该漏洞的CVSS评分为5.5,属于中危级别,攻击向量为本地,需要低权限即可触发,无需用户交互。虽然机密性和完整性不受影响,但该漏洞可导致系统可用性下降(高可用性影响),长时间运行可能耗尽内核内存资源,影响系统稳定性和其他进程正常运行。该漏洞影响多个Linux内核稳定版本,官方已通过多个补丁提交进行修复。
该漏洞的根本原因在于TUN驱动的tun_get_user函数和__tun_detach函数之间存在竞态条件。具体而言,当启用NAPI和IFF_MULTI_QUEUE特性的TUN设备的某个文件描述符队列被分离(detached)后,write()系统调用和ioctl(IFF_DETACH_QUEUE)可能并发执行。
在原始代码中,tun_get_user函数检查tfile->detached标志的时机与加锁时机不当:write()路径首先检查tfile->detached状态(此时为false),然后获取queue->lock自旋锁并执行__skb_queue_tail将skb加入队列;而与此同时,ioctl(IFF_DETACH_QUEUE)路径在__tun_detach中执行tun_disable_queue,将tfile->detached设置为true并调用tun_queue_purge清理队列。由于检查和加锁之间存在时间窗口,可能导致skb在队列已被分离后仍然被加入写入队列(tfile->sk.sk_write_queue),而这些skb在队列关闭时不会被正确释放,造成内存泄漏。
修复方案是在tun_get_user中,在queue->lock自旋锁的保护下检查tfile->detached标志,确保在将skb加入队列之前队列未被分离。同时对IFF_NAPI_FRAGS也做相同的检查处理,以防止类似的竞态条件。