xref: /linux/tools/testing/selftests/bpf/progs/task_work_fail.c (revision 4f38da1f027ea2c9f01bb71daa7a299c191b6940)
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