xref: /linux/tools/testing/selftests/bpf/progs/test_bpf_nf_fail.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0
2 #define BPF_NO_KFUNC_PROTOTYPES
3 #include <vmlinux.h>
4 #include <bpf/bpf_tracing.h>
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_core_read.h>
7 #include "bpf_misc.h"
8 
9 struct nf_conn;
10 
11 struct bpf_ct_opts___local {
12 	s32 netns_id;
13 	s32 error;
14 	u8 l4proto;
15 	u8 reserved[3];
16 } __attribute__((preserve_access_index));
17 
18 struct nf_conn *bpf_skb_ct_alloc(struct __sk_buff *, struct bpf_sock_tuple *, u32,
19 				 struct bpf_ct_opts___local *, u32) __ksym;
20 struct nf_conn *bpf_skb_ct_lookup(struct __sk_buff *, struct bpf_sock_tuple *, u32,
21 				  struct bpf_ct_opts___local *, u32) __ksym;
22 struct nf_conn *bpf_xdp_ct_alloc(struct xdp_md *, struct bpf_sock_tuple *, u32,
23 				 struct bpf_ct_opts___local *, u32) __ksym;
24 struct nf_conn *bpf_xdp_ct_lookup(struct xdp_md *, struct bpf_sock_tuple *, u32,
25 				  struct bpf_ct_opts___local *, u32) __ksym;
26 struct nf_conn *bpf_ct_insert_entry(struct nf_conn *) __ksym;
27 void bpf_ct_release(struct nf_conn *) __ksym;
28 void bpf_ct_set_timeout(struct nf_conn *, u32) __ksym;
29 int bpf_ct_change_timeout(struct nf_conn *, u32) __ksym;
30 int bpf_ct_set_status(struct nf_conn *, u32) __ksym;
31 int bpf_ct_change_status(struct nf_conn *, u32) __ksym;
32 
33 SEC("?tc")
34 int alloc_release(struct __sk_buff *ctx)
35 {
36 	struct bpf_ct_opts___local opts = {};
37 	struct bpf_sock_tuple tup = {};
38 	struct nf_conn *ct;
39 
40 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
41 	if (!ct)
42 		return 0;
43 	bpf_ct_release(ct);
44 	return 0;
45 }
46 
47 SEC("?tc")
48 int insert_insert(struct __sk_buff *ctx)
49 {
50 	struct bpf_ct_opts___local opts = {};
51 	struct bpf_sock_tuple tup = {};
52 	struct nf_conn *ct;
53 
54 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
55 	if (!ct)
56 		return 0;
57 	ct = bpf_ct_insert_entry(ct);
58 	if (!ct)
59 		return 0;
60 	ct = bpf_ct_insert_entry(ct);
61 	return 0;
62 }
63 
64 SEC("?tc")
65 int lookup_insert(struct __sk_buff *ctx)
66 {
67 	struct bpf_ct_opts___local opts = {};
68 	struct bpf_sock_tuple tup = {};
69 	struct nf_conn *ct;
70 
71 	ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
72 	if (!ct)
73 		return 0;
74 	bpf_ct_insert_entry(ct);
75 	return 0;
76 }
77 
78 SEC("?tc")
79 int write_not_allowlisted_field(struct __sk_buff *ctx)
80 {
81 	struct bpf_ct_opts___local opts = {};
82 	struct bpf_sock_tuple tup = {};
83 	struct nf_conn *ct;
84 
85 	ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
86 	if (!ct)
87 		return 0;
88 	ct->status = 0xF00;
89 	return 0;
90 }
91 
92 SEC("?tc")
93 int set_timeout_after_insert(struct __sk_buff *ctx)
94 {
95 	struct bpf_ct_opts___local opts = {};
96 	struct bpf_sock_tuple tup = {};
97 	struct nf_conn *ct;
98 
99 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
100 	if (!ct)
101 		return 0;
102 	ct = bpf_ct_insert_entry(ct);
103 	if (!ct)
104 		return 0;
105 	bpf_ct_set_timeout(ct, 0);
106 	return 0;
107 }
108 
109 SEC("?tc")
110 int set_status_after_insert(struct __sk_buff *ctx)
111 {
112 	struct bpf_ct_opts___local opts = {};
113 	struct bpf_sock_tuple tup = {};
114 	struct nf_conn *ct;
115 
116 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
117 	if (!ct)
118 		return 0;
119 	ct = bpf_ct_insert_entry(ct);
120 	if (!ct)
121 		return 0;
122 	bpf_ct_set_status(ct, 0);
123 	return 0;
124 }
125 
126 SEC("?tc")
127 int change_timeout_after_alloc(struct __sk_buff *ctx)
128 {
129 	struct bpf_ct_opts___local opts = {};
130 	struct bpf_sock_tuple tup = {};
131 	struct nf_conn *ct;
132 
133 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
134 	if (!ct)
135 		return 0;
136 	bpf_ct_change_timeout(ct, 0);
137 	return 0;
138 }
139 
140 SEC("?tc")
141 int change_status_after_alloc(struct __sk_buff *ctx)
142 {
143 	struct bpf_ct_opts___local opts = {};
144 	struct bpf_sock_tuple tup = {};
145 	struct nf_conn *ct;
146 
147 	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
148 	if (!ct)
149 		return 0;
150 	bpf_ct_change_status(ct, 0);
151 	return 0;
152 }
153 
154 SEC("?tc")
155 __failure __msg("Possibly NULL pointer passed to trusted arg1")
156 int lookup_null_bpf_tuple(struct __sk_buff *ctx)
157 {
158 	struct bpf_ct_opts___local opts = {};
159 	struct nf_conn *ct;
160 
161 	ct = bpf_skb_ct_lookup(ctx, NULL, 0, &opts, sizeof(opts));
162 	if (ct)
163 		bpf_ct_release(ct);
164 	return 0;
165 }
166 
167 SEC("?tc")
168 __failure __msg("Possibly NULL pointer passed to trusted arg3")
169 int lookup_null_bpf_opts(struct __sk_buff *ctx)
170 {
171 	struct bpf_sock_tuple tup = {};
172 	struct nf_conn *ct;
173 
174 	ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), NULL, sizeof(struct bpf_ct_opts___local));
175 	if (ct)
176 		bpf_ct_release(ct);
177 	return 0;
178 }
179 
180 SEC("?xdp")
181 __failure __msg("Possibly NULL pointer passed to trusted arg1")
182 int xdp_lookup_null_bpf_tuple(struct xdp_md *ctx)
183 {
184 	struct bpf_ct_opts___local opts = {};
185 	struct nf_conn *ct;
186 
187 	ct = bpf_xdp_ct_lookup(ctx, NULL, 0, &opts, sizeof(opts));
188 	if (ct)
189 		bpf_ct_release(ct);
190 	return 0;
191 }
192 
193 SEC("?xdp")
194 __failure __msg("Possibly NULL pointer passed to trusted arg3")
195 int xdp_lookup_null_bpf_opts(struct xdp_md *ctx)
196 {
197 	struct bpf_sock_tuple tup = {};
198 	struct nf_conn *ct;
199 
200 	ct = bpf_xdp_ct_lookup(ctx, &tup, sizeof(tup.ipv4), NULL, sizeof(struct bpf_ct_opts___local));
201 	if (ct)
202 		bpf_ct_release(ct);
203 	return 0;
204 }
205 
206 char _license[] SEC("license") = "GPL";
207