1*39fd74dfSMykyta Yatsenko // SPDX-License-Identifier: GPL-2.0 2*39fd74dfSMykyta Yatsenko /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3*39fd74dfSMykyta Yatsenko 4*39fd74dfSMykyta Yatsenko #include <vmlinux.h> 5*39fd74dfSMykyta Yatsenko #include <string.h> 6*39fd74dfSMykyta Yatsenko #include <stdbool.h> 7*39fd74dfSMykyta Yatsenko #include <bpf/bpf_helpers.h> 8*39fd74dfSMykyta Yatsenko #include <bpf/bpf_tracing.h> 9*39fd74dfSMykyta Yatsenko #include "bpf_misc.h" 10*39fd74dfSMykyta Yatsenko 11*39fd74dfSMykyta Yatsenko char _license[] SEC("license") = "GPL"; 12*39fd74dfSMykyta Yatsenko 13*39fd74dfSMykyta Yatsenko const void *user_ptr = NULL; 14*39fd74dfSMykyta Yatsenko 15*39fd74dfSMykyta Yatsenko struct elem { 16*39fd74dfSMykyta Yatsenko char data[128]; 17*39fd74dfSMykyta Yatsenko struct bpf_task_work tw; 18*39fd74dfSMykyta Yatsenko }; 19*39fd74dfSMykyta Yatsenko 20*39fd74dfSMykyta Yatsenko struct { 21*39fd74dfSMykyta Yatsenko __uint(type, BPF_MAP_TYPE_HASH); 22*39fd74dfSMykyta Yatsenko __uint(map_flags, BPF_F_NO_PREALLOC); 23*39fd74dfSMykyta Yatsenko __uint(max_entries, 1); 24*39fd74dfSMykyta Yatsenko __type(key, int); 25*39fd74dfSMykyta Yatsenko __type(value, struct elem); 26*39fd74dfSMykyta Yatsenko } hmap SEC(".maps"); 27*39fd74dfSMykyta Yatsenko 28*39fd74dfSMykyta Yatsenko struct { 29*39fd74dfSMykyta Yatsenko __uint(type, BPF_MAP_TYPE_ARRAY); 30*39fd74dfSMykyta Yatsenko __uint(max_entries, 1); 31*39fd74dfSMykyta Yatsenko __type(key, int); 32*39fd74dfSMykyta Yatsenko __type(value, struct elem); 33*39fd74dfSMykyta Yatsenko } arrmap SEC(".maps"); 34*39fd74dfSMykyta Yatsenko 35*39fd74dfSMykyta Yatsenko static int process_work(struct bpf_map *map, void *key, void *value) 36*39fd74dfSMykyta Yatsenko { 37*39fd74dfSMykyta Yatsenko struct elem *work = value; 38*39fd74dfSMykyta Yatsenko 39*39fd74dfSMykyta Yatsenko bpf_copy_from_user_str(work->data, sizeof(work->data), (const void *)user_ptr, 0); 40*39fd74dfSMykyta Yatsenko return 0; 41*39fd74dfSMykyta Yatsenko } 42*39fd74dfSMykyta Yatsenko 43*39fd74dfSMykyta Yatsenko int key = 0; 44*39fd74dfSMykyta Yatsenko 45*39fd74dfSMykyta Yatsenko SEC("perf_event") 46*39fd74dfSMykyta Yatsenko __failure __msg("doesn't match map pointer in R3") 47*39fd74dfSMykyta Yatsenko int mismatch_map(struct pt_regs *args) 48*39fd74dfSMykyta Yatsenko { 49*39fd74dfSMykyta Yatsenko struct elem *work; 50*39fd74dfSMykyta Yatsenko struct task_struct *task; 51*39fd74dfSMykyta Yatsenko 52*39fd74dfSMykyta Yatsenko task = bpf_get_current_task_btf(); 53*39fd74dfSMykyta Yatsenko work = bpf_map_lookup_elem(&arrmap, &key); 54*39fd74dfSMykyta Yatsenko if (!work) 55*39fd74dfSMykyta Yatsenko return 0; 56*39fd74dfSMykyta Yatsenko bpf_task_work_schedule_resume(task, &work->tw, &hmap, process_work, NULL); 57*39fd74dfSMykyta Yatsenko return 0; 58*39fd74dfSMykyta Yatsenko } 59*39fd74dfSMykyta Yatsenko 60*39fd74dfSMykyta Yatsenko SEC("perf_event") 61*39fd74dfSMykyta Yatsenko __failure __msg("arg#1 doesn't point to a map value") 62*39fd74dfSMykyta Yatsenko int no_map_task_work(struct pt_regs *args) 63*39fd74dfSMykyta Yatsenko { 64*39fd74dfSMykyta Yatsenko struct task_struct *task; 65*39fd74dfSMykyta Yatsenko struct bpf_task_work tw; 66*39fd74dfSMykyta Yatsenko 67*39fd74dfSMykyta Yatsenko task = bpf_get_current_task_btf(); 68*39fd74dfSMykyta Yatsenko bpf_task_work_schedule_resume(task, &tw, &hmap, process_work, NULL); 69*39fd74dfSMykyta Yatsenko return 0; 70*39fd74dfSMykyta Yatsenko } 71*39fd74dfSMykyta Yatsenko 72*39fd74dfSMykyta Yatsenko SEC("perf_event") 73*39fd74dfSMykyta Yatsenko __failure __msg("Possibly NULL pointer passed to trusted arg1") 74*39fd74dfSMykyta Yatsenko int task_work_null(struct pt_regs *args) 75*39fd74dfSMykyta Yatsenko { 76*39fd74dfSMykyta Yatsenko struct task_struct *task; 77*39fd74dfSMykyta Yatsenko 78*39fd74dfSMykyta Yatsenko task = bpf_get_current_task_btf(); 79*39fd74dfSMykyta Yatsenko bpf_task_work_schedule_resume(task, NULL, &hmap, process_work, NULL); 80*39fd74dfSMykyta Yatsenko return 0; 81*39fd74dfSMykyta Yatsenko } 82*39fd74dfSMykyta Yatsenko 83*39fd74dfSMykyta Yatsenko SEC("perf_event") 84*39fd74dfSMykyta Yatsenko __failure __msg("Possibly NULL pointer passed to trusted arg2") 85*39fd74dfSMykyta Yatsenko int map_null(struct pt_regs *args) 86*39fd74dfSMykyta Yatsenko { 87*39fd74dfSMykyta Yatsenko struct elem *work; 88*39fd74dfSMykyta Yatsenko struct task_struct *task; 89*39fd74dfSMykyta Yatsenko 90*39fd74dfSMykyta Yatsenko task = bpf_get_current_task_btf(); 91*39fd74dfSMykyta Yatsenko work = bpf_map_lookup_elem(&arrmap, &key); 92*39fd74dfSMykyta Yatsenko if (!work) 93*39fd74dfSMykyta Yatsenko return 0; 94*39fd74dfSMykyta Yatsenko bpf_task_work_schedule_resume(task, &work->tw, NULL, process_work, NULL); 95*39fd74dfSMykyta Yatsenko return 0; 96*39fd74dfSMykyta Yatsenko } 97