xref: /linux/tools/testing/selftests/bpf/progs/uptr_failure.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3 
4 #include <vmlinux.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_experimental.h"
7 #include "bpf_misc.h"
8 #include "uptr_test_common.h"
9 
10 struct {
11 	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);
12 	__uint(map_flags, BPF_F_NO_PREALLOC);
13 	__type(key, int);
14 	__type(value, struct value_type);
15 } datamap SEC(".maps");
16 
17 SEC("?syscall")
18 __failure __msg("store to uptr disallowed")
19 int uptr_write(const void *ctx)
20 {
21 	struct task_struct *task;
22 	struct value_type *v;
23 
24 	task = bpf_get_current_task_btf();
25 	v = bpf_task_storage_get(&datamap, task, 0,
26 				 BPF_LOCAL_STORAGE_GET_F_CREATE);
27 	if (!v)
28 		return 0;
29 
30 	v->udata = NULL;
31 	return 0;
32 }
33 
34 SEC("?syscall")
35 __failure __msg("store to uptr disallowed")
36 int uptr_write_nested(const void *ctx)
37 {
38 	struct task_struct *task;
39 	struct value_type *v;
40 
41 	task = bpf_get_current_task_btf();
42 	v = bpf_task_storage_get(&datamap, task, 0,
43 				 BPF_LOCAL_STORAGE_GET_F_CREATE);
44 	if (!v)
45 		return 0;
46 
47 	v->nested.udata = NULL;
48 	return 0;
49 }
50 
51 SEC("?syscall")
52 __failure __msg("R1 invalid mem access 'mem_or_null'")
53 int uptr_no_null_check(const void *ctx)
54 {
55 	struct task_struct *task;
56 	struct value_type *v;
57 
58 	task = bpf_get_current_task_btf();
59 	v = bpf_task_storage_get(&datamap, task, 0,
60 				 BPF_LOCAL_STORAGE_GET_F_CREATE);
61 	if (!v)
62 		return 0;
63 
64 	v->udata->result = 0;
65 
66 	return 0;
67 }
68 
69 SEC("?syscall")
70 __failure __msg("doesn't point to kptr")
71 int uptr_kptr_xchg(const void *ctx)
72 {
73 	struct task_struct *task;
74 	struct value_type *v;
75 
76 	task = bpf_get_current_task_btf();
77 	v = bpf_task_storage_get(&datamap, task, 0,
78 				 BPF_LOCAL_STORAGE_GET_F_CREATE);
79 	if (!v)
80 		return 0;
81 
82 	bpf_kptr_xchg(&v->udata, NULL);
83 
84 	return 0;
85 }
86 
87 SEC("?syscall")
88 __failure __msg("invalid mem access 'scalar'")
89 int uptr_obj_new(const void *ctx)
90 {
91 	struct value_type *v;
92 
93 	v = bpf_obj_new(typeof(*v));
94 	if (!v)
95 		return 0;
96 
97 	if (v->udata)
98 		v->udata->result = 0;
99 
100 	bpf_obj_drop(v);
101 
102 	return 0;
103 }
104 
105 char _license[] SEC("license") = "GPL";
106