278 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */3#include <linux/bpf.h>4#include <bpf/bpf_helpers.h>5#include <bpf/bpf_tracing.h>6#include <stdbool.h>7#include <stdatomic.h>8#include "bpf_arena_common.h"9 10struct {11 __uint(type, BPF_MAP_TYPE_ARENA);12 __uint(map_flags, BPF_F_MMAPABLE);13 __uint(max_entries, 10); /* number of pages */14#ifdef __TARGET_ARCH_arm6415 __ulong(map_extra, 0x1ull << 32); /* start of mmap() region */16#else17 __ulong(map_extra, 0x1ull << 44); /* start of mmap() region */18#endif19} arena SEC(".maps");20 21#if defined(ENABLE_ATOMICS_TESTS) && defined(__BPF_FEATURE_ADDR_SPACE_CAST)22bool skip_tests __attribute((__section__(".data"))) = false;23#else24bool skip_tests = true;25#endif26 27__u32 pid = 0;28 29__u64 __arena_global add64_value = 1;30__u64 __arena_global add64_result = 0;31__u32 __arena_global add32_value = 1;32__u32 __arena_global add32_result = 0;33__u64 __arena_global add_stack_value_copy = 0;34__u64 __arena_global add_stack_result = 0;35__u64 __arena_global add_noreturn_value = 1;36 37SEC("raw_tp/sys_enter")38int add(const void *ctx)39{40 if (pid != (bpf_get_current_pid_tgid() >> 32))41 return 0;42#ifdef ENABLE_ATOMICS_TESTS43 __u64 add_stack_value = 1;44 45 add64_result = __sync_fetch_and_add(&add64_value, 2);46 add32_result = __sync_fetch_and_add(&add32_value, 2);47 add_stack_result = __sync_fetch_and_add(&add_stack_value, 2);48 add_stack_value_copy = add_stack_value;49 __sync_fetch_and_add(&add_noreturn_value, 2);50#endif51 52 return 0;53}54 55__s64 __arena_global sub64_value = 1;56__s64 __arena_global sub64_result = 0;57__s32 __arena_global sub32_value = 1;58__s32 __arena_global sub32_result = 0;59__s64 __arena_global sub_stack_value_copy = 0;60__s64 __arena_global sub_stack_result = 0;61__s64 __arena_global sub_noreturn_value = 1;62 63SEC("raw_tp/sys_enter")64int sub(const void *ctx)65{66 if (pid != (bpf_get_current_pid_tgid() >> 32))67 return 0;68#ifdef ENABLE_ATOMICS_TESTS69 __u64 sub_stack_value = 1;70 71 sub64_result = __sync_fetch_and_sub(&sub64_value, 2);72 sub32_result = __sync_fetch_and_sub(&sub32_value, 2);73 sub_stack_result = __sync_fetch_and_sub(&sub_stack_value, 2);74 sub_stack_value_copy = sub_stack_value;75 __sync_fetch_and_sub(&sub_noreturn_value, 2);76#endif77 78 return 0;79}80 81#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING82_Atomic __u64 __arena_global and64_value = (0x110ull << 32);83_Atomic __u32 __arena_global and32_value = 0x110;84#else85__u64 __arena_global and64_value = (0x110ull << 32);86__u32 __arena_global and32_value = 0x110;87#endif88 89SEC("raw_tp/sys_enter")90int and(const void *ctx)91{92 if (pid != (bpf_get_current_pid_tgid() >> 32))93 return 0;94#ifdef ENABLE_ATOMICS_TESTS95#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING96 __c11_atomic_fetch_and(&and64_value, 0x011ull << 32, memory_order_relaxed);97 __c11_atomic_fetch_and(&and32_value, 0x011, memory_order_relaxed);98#else99 __sync_fetch_and_and(&and64_value, 0x011ull << 32);100 __sync_fetch_and_and(&and32_value, 0x011);101#endif102#endif103 104 return 0;105}106 107#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING108_Atomic __u32 __arena_global or32_value = 0x110;109_Atomic __u64 __arena_global or64_value = (0x110ull << 32);110#else111__u32 __arena_global or32_value = 0x110;112__u64 __arena_global or64_value = (0x110ull << 32);113#endif114 115SEC("raw_tp/sys_enter")116int or(const void *ctx)117{118 if (pid != (bpf_get_current_pid_tgid() >> 32))119 return 0;120#ifdef ENABLE_ATOMICS_TESTS121#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING122 __c11_atomic_fetch_or(&or64_value, 0x011ull << 32, memory_order_relaxed);123 __c11_atomic_fetch_or(&or32_value, 0x011, memory_order_relaxed);124#else125 __sync_fetch_and_or(&or64_value, 0x011ull << 32);126 __sync_fetch_and_or(&or32_value, 0x011);127#endif128#endif129 130 return 0;131}132 133#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING134_Atomic __u64 __arena_global xor64_value = (0x110ull << 32);135_Atomic __u32 __arena_global xor32_value = 0x110;136#else137__u64 __arena_global xor64_value = (0x110ull << 32);138__u32 __arena_global xor32_value = 0x110;139#endif140 141SEC("raw_tp/sys_enter")142int xor(const void *ctx)143{144 if (pid != (bpf_get_current_pid_tgid() >> 32))145 return 0;146#ifdef ENABLE_ATOMICS_TESTS147#ifdef __BPF_FEATURE_ATOMIC_MEM_ORDERING148 __c11_atomic_fetch_xor(&xor64_value, 0x011ull << 32, memory_order_relaxed);149 __c11_atomic_fetch_xor(&xor32_value, 0x011, memory_order_relaxed);150#else151 __sync_fetch_and_xor(&xor64_value, 0x011ull << 32);152 __sync_fetch_and_xor(&xor32_value, 0x011);153#endif154#endif155 156 return 0;157}158 159__u32 __arena_global cmpxchg32_value = 1;160__u32 __arena_global cmpxchg32_result_fail = 0;161__u32 __arena_global cmpxchg32_result_succeed = 0;162__u64 __arena_global cmpxchg64_value = 1;163__u64 __arena_global cmpxchg64_result_fail = 0;164__u64 __arena_global cmpxchg64_result_succeed = 0;165 166SEC("raw_tp/sys_enter")167int cmpxchg(const void *ctx)168{169 if (pid != (bpf_get_current_pid_tgid() >> 32))170 return 0;171#ifdef ENABLE_ATOMICS_TESTS172 cmpxchg64_result_fail = __sync_val_compare_and_swap(&cmpxchg64_value, 0, 3);173 cmpxchg64_result_succeed = __sync_val_compare_and_swap(&cmpxchg64_value, 1, 2);174 175 cmpxchg32_result_fail = __sync_val_compare_and_swap(&cmpxchg32_value, 0, 3);176 cmpxchg32_result_succeed = __sync_val_compare_and_swap(&cmpxchg32_value, 1, 2);177#endif178 179 return 0;180}181 182__u64 __arena_global xchg64_value = 1;183__u64 __arena_global xchg64_result = 0;184__u32 __arena_global xchg32_value = 1;185__u32 __arena_global xchg32_result = 0;186 187SEC("raw_tp/sys_enter")188int xchg(const void *ctx)189{190 if (pid != (bpf_get_current_pid_tgid() >> 32))191 return 0;192#ifdef ENABLE_ATOMICS_TESTS193 __u64 val64 = 2;194 __u32 val32 = 2;195 196 xchg64_result = __sync_lock_test_and_set(&xchg64_value, val64);197 xchg32_result = __sync_lock_test_and_set(&xchg32_value, val32);198#endif199 200 return 0;201}202 203__u64 __arena_global uaf_sink;204volatile __u64 __arena_global uaf_recovery_fails;205 206SEC("syscall")207int uaf(const void *ctx)208{209 if (pid != (bpf_get_current_pid_tgid() >> 32))210 return 0;211#if defined(ENABLE_ATOMICS_TESTS) && !defined(__TARGET_ARCH_arm64) && \212 !defined(__TARGET_ARCH_x86)213 __u32 __arena *page32;214 __u64 __arena *page64;215 void __arena *page;216 217 page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);218 bpf_arena_free_pages(&arena, page, 1);219 uaf_recovery_fails = 24;220 221 page32 = (__u32 __arena *)page;222 uaf_sink += __sync_fetch_and_add(page32, 1);223 uaf_recovery_fails -= 1;224 __sync_add_and_fetch(page32, 1);225 uaf_recovery_fails -= 1;226 uaf_sink += __sync_fetch_and_sub(page32, 1);227 uaf_recovery_fails -= 1;228 __sync_sub_and_fetch(page32, 1);229 uaf_recovery_fails -= 1;230 uaf_sink += __sync_fetch_and_and(page32, 1);231 uaf_recovery_fails -= 1;232 __sync_and_and_fetch(page32, 1);233 uaf_recovery_fails -= 1;234 uaf_sink += __sync_fetch_and_or(page32, 1);235 uaf_recovery_fails -= 1;236 __sync_or_and_fetch(page32, 1);237 uaf_recovery_fails -= 1;238 uaf_sink += __sync_fetch_and_xor(page32, 1);239 uaf_recovery_fails -= 1;240 __sync_xor_and_fetch(page32, 1);241 uaf_recovery_fails -= 1;242 uaf_sink += __sync_val_compare_and_swap(page32, 0, 1);243 uaf_recovery_fails -= 1;244 uaf_sink += __sync_lock_test_and_set(page32, 1);245 uaf_recovery_fails -= 1;246 247 page64 = (__u64 __arena *)page;248 uaf_sink += __sync_fetch_and_add(page64, 1);249 uaf_recovery_fails -= 1;250 __sync_add_and_fetch(page64, 1);251 uaf_recovery_fails -= 1;252 uaf_sink += __sync_fetch_and_sub(page64, 1);253 uaf_recovery_fails -= 1;254 __sync_sub_and_fetch(page64, 1);255 uaf_recovery_fails -= 1;256 uaf_sink += __sync_fetch_and_and(page64, 1);257 uaf_recovery_fails -= 1;258 __sync_and_and_fetch(page64, 1);259 uaf_recovery_fails -= 1;260 uaf_sink += __sync_fetch_and_or(page64, 1);261 uaf_recovery_fails -= 1;262 __sync_or_and_fetch(page64, 1);263 uaf_recovery_fails -= 1;264 uaf_sink += __sync_fetch_and_xor(page64, 1);265 uaf_recovery_fails -= 1;266 __sync_xor_and_fetch(page64, 1);267 uaf_recovery_fails -= 1;268 uaf_sink += __sync_val_compare_and_swap(page64, 0, 1);269 uaf_recovery_fails -= 1;270 uaf_sink += __sync_lock_test_and_set(page64, 1);271 uaf_recovery_fails -= 1;272#endif273 274 return 0;275}276 277char _license[] SEC("license") = "GPL";278