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