152 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */3 4#define BPF_NO_KFUNC_PROTOTYPES5#include <vmlinux.h>6#include <bpf/bpf_helpers.h>7#include <bpf/bpf_tracing.h>8#include "bpf_misc.h"9#include "bpf_experimental.h"10#include "bpf_arena_common.h"11 12struct {13 __uint(type, BPF_MAP_TYPE_ARENA);14 __uint(map_flags, BPF_F_MMAPABLE);15 __uint(max_entries, 2); /* arena of two pages close to 32-bit boundary*/16#ifdef __TARGET_ARCH_arm6417 __ulong(map_extra, (1ull << 32) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */18#else19 __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */20#endif21} arena SEC(".maps");22 23SEC("syscall")24__success __retval(0)25int basic_alloc1(void *ctx)26{27#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)28 volatile int __arena *page1, *page2, *no_page, *page3;29 30 page1 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);31 if (!page1)32 return 1;33 *page1 = 1;34 page2 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);35 if (!page2)36 return 2;37 *page2 = 2;38 no_page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);39 if (no_page)40 return 3;41 if (*page1 != 1)42 return 4;43 if (*page2 != 2)44 return 5;45 bpf_arena_free_pages(&arena, (void __arena *)page2, 1);46 if (*page1 != 1)47 return 6;48 if (*page2 != 0) /* use-after-free should return 0 */49 return 7;50 page3 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);51 if (!page3)52 return 8;53 *page3 = 3;54 if (page2 != page3)55 return 9;56 if (*page1 != 1)57 return 10;58#endif59 return 0;60}61 62SEC("syscall")63__success __retval(0)64int basic_alloc2(void *ctx)65{66#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)67 volatile char __arena *page1, *page2, *page3, *page4;68 69 page1 = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);70 if (!page1)71 return 1;72 page2 = page1 + __PAGE_SIZE;73 page3 = page1 + __PAGE_SIZE * 2;74 page4 = page1 - __PAGE_SIZE;75 *page1 = 1;76 *page2 = 2;77 *page3 = 3;78 *page4 = 4;79 if (*page1 != 1)80 return 1;81 if (*page2 != 2)82 return 2;83 if (*page3 != 0)84 return 3;85 if (*page4 != 0)86 return 4;87 bpf_arena_free_pages(&arena, (void __arena *)page1, 2);88 if (*page1 != 0)89 return 5;90 if (*page2 != 0)91 return 6;92 if (*page3 != 0)93 return 7;94 if (*page4 != 0)95 return 8;96#endif97 return 0;98}99 100struct bpf_arena___l {101 struct bpf_map map;102} __attribute__((preserve_access_index));103 104SEC("syscall")105__success __retval(0) __log_level(2)106int basic_alloc3(void *ctx)107{108 struct bpf_arena___l *ar = (struct bpf_arena___l *)&arena;109 volatile char __arena *pages;110 111 pages = bpf_arena_alloc_pages(&ar->map, NULL, ar->map.max_entries, NUMA_NO_NODE, 0);112 if (!pages)113 return 1;114 return 0;115}116 117SEC("iter.s/bpf_map")118__success __log_level(2)119int iter_maps1(struct bpf_iter__bpf_map *ctx)120{121 struct bpf_map *map = ctx->map;122 123 if (!map)124 return 0;125 bpf_arena_alloc_pages(map, NULL, map->max_entries, 0, 0);126 return 0;127}128 129SEC("iter.s/bpf_map")130__failure __msg("expected pointer to STRUCT bpf_map")131int iter_maps2(struct bpf_iter__bpf_map *ctx)132{133 struct seq_file *seq = ctx->meta->seq;134 135 bpf_arena_alloc_pages((void *)seq, NULL, 1, 0, 0);136 return 0;137}138 139SEC("iter.s/bpf_map")140__failure __msg("untrusted_ptr_bpf_map")141int iter_maps3(struct bpf_iter__bpf_map *ctx)142{143 struct bpf_map *map = ctx->map;144 145 if (!map)146 return 0;147 bpf_arena_alloc_pages(map->inner_map_meta, NULL, map->max_entries, 0, 0);148 return 0;149}150 151char _license[] SEC("license") = "GPL";152