• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2017 Facebook
3  */
4 #include <linux/bpf.h>
5 #include <linux/slab.h>
6 #include <linux/vmalloc.h>
7 #include <linux/etherdevice.h>
8 #include <linux/filter.h>
9 #include <linux/sched/signal.h>
10 #include <net/bpf_sk_storage.h>
11 #include <net/sock.h>
12 #include <net/tcp.h>
13 #include <linux/error-injection.h>
14 #include <linux/smp.h>
15 
16 #define CREATE_TRACE_POINTS
17 #include <trace/events/bpf_test_run.h>
18 
bpf_test_run(struct bpf_prog * prog,void * ctx,u32 repeat,u32 * retval,u32 * time,bool xdp)19 static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
20 			u32 *retval, u32 *time, bool xdp)
21 {
22 	struct bpf_prog_array_item item = {.prog = prog};
23 	struct bpf_run_ctx *old_ctx;
24 	struct bpf_cg_run_ctx run_ctx;
25 	enum bpf_cgroup_storage_type stype;
26 	u64 time_start, time_spent = 0;
27 	int ret = 0;
28 	u32 i;
29 
30 	for_each_cgroup_storage_type(stype) {
31 		item.cgroup_storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
32 		if (IS_ERR(item.cgroup_storage[stype])) {
33 			item.cgroup_storage[stype] = NULL;
34 			for_each_cgroup_storage_type(stype)
35 				bpf_cgroup_storage_free(item.cgroup_storage[stype]);
36 			return -ENOMEM;
37 		}
38 	}
39 
40 	if (!repeat)
41 		repeat = 1;
42 
43 	rcu_read_lock();
44 	migrate_disable();
45 	time_start = ktime_get_ns();
46 	old_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
47 	for (i = 0; i < repeat; i++) {
48 		run_ctx.prog_item = &item;
49 
50 		if (xdp)
51 			*retval = bpf_prog_run_xdp(prog, ctx);
52 		else
53 			*retval = BPF_PROG_RUN(prog, ctx);
54 
55 		if (signal_pending(current)) {
56 			ret = -EINTR;
57 			break;
58 		}
59 
60 		if (need_resched()) {
61 			time_spent += ktime_get_ns() - time_start;
62 			migrate_enable();
63 			rcu_read_unlock();
64 
65 			cond_resched();
66 
67 			rcu_read_lock();
68 			migrate_disable();
69 			time_start = ktime_get_ns();
70 		}
71 	}
72 	bpf_reset_run_ctx(old_ctx);
73 	time_spent += ktime_get_ns() - time_start;
74 	migrate_enable();
75 	rcu_read_unlock();
76 
77 	do_div(time_spent, repeat);
78 	*time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
79 
80 	for_each_cgroup_storage_type(stype)
81 		bpf_cgroup_storage_free(item.cgroup_storage[stype]);
82 
83 	return ret;
84 }
85 
bpf_test_finish(const union bpf_attr * kattr,union bpf_attr __user * uattr,const void * data,u32 size,u32 retval,u32 duration)86 static int bpf_test_finish(const union bpf_attr *kattr,
87 			   union bpf_attr __user *uattr, const void *data,
88 			   u32 size, u32 retval, u32 duration)
89 {
90 	void __user *data_out = u64_to_user_ptr(kattr->test.data_out);
91 	int err = -EFAULT;
92 	u32 copy_size = size;
93 
94 	/* Clamp copy if the user has provided a size hint, but copy the full
95 	 * buffer if not to retain old behaviour.
96 	 */
97 	if (kattr->test.data_size_out &&
98 	    copy_size > kattr->test.data_size_out) {
99 		copy_size = kattr->test.data_size_out;
100 		err = -ENOSPC;
101 	}
102 
103 	if (data_out && copy_to_user(data_out, data, copy_size))
104 		goto out;
105 	if (copy_to_user(&uattr->test.data_size_out, &size, sizeof(size)))
106 		goto out;
107 	if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
108 		goto out;
109 	if (copy_to_user(&uattr->test.duration, &duration, sizeof(duration)))
110 		goto out;
111 	if (err != -ENOSPC)
112 		err = 0;
113 out:
114 	trace_bpf_test_finish(&err);
115 	return err;
116 }
117 
118 /* Integer types of various sizes and pointer combinations cover variety of
119  * architecture dependent calling conventions. 7+ can be supported in the
120  * future.
121  */
122 __diag_push();
123 __diag_ignore(GCC, 8, "-Wmissing-prototypes",
124 	      "Global functions as their definitions will be in vmlinux BTF");
bpf_fentry_test1(int a)125 int noinline bpf_fentry_test1(int a)
126 {
127 	return a + 1;
128 }
129 
bpf_fentry_test2(int a,u64 b)130 int noinline bpf_fentry_test2(int a, u64 b)
131 {
132 	return a + b;
133 }
134 
bpf_fentry_test3(char a,int b,u64 c)135 int noinline bpf_fentry_test3(char a, int b, u64 c)
136 {
137 	return a + b + c;
138 }
139 
bpf_fentry_test4(void * a,char b,int c,u64 d)140 int noinline bpf_fentry_test4(void *a, char b, int c, u64 d)
141 {
142 	return (long)a + b + c + d;
143 }
144 
bpf_fentry_test5(u64 a,void * b,short c,int d,u64 e)145 int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e)
146 {
147 	return a + (long)b + c + d + e;
148 }
149 
bpf_fentry_test6(u64 a,void * b,short c,int d,void * e,u64 f)150 int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f)
151 {
152 	return a + (long)b + c + d + (long)e + f;
153 }
154 
155 struct bpf_fentry_test_t {
156 	struct bpf_fentry_test_t *a;
157 };
158 
bpf_fentry_test7(struct bpf_fentry_test_t * arg)159 int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg)
160 {
161 	return (long)arg;
162 }
163 
bpf_fentry_test8(struct bpf_fentry_test_t * arg)164 int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg)
165 {
166 	return (long)arg->a;
167 }
168 
bpf_modify_return_test(int a,int * b)169 int noinline bpf_modify_return_test(int a, int *b)
170 {
171 	*b += 1;
172 	return a + *b;
173 }
174 __diag_pop();
175 
176 ALLOW_ERROR_INJECTION(bpf_modify_return_test, ERRNO);
177 
bpf_test_init(const union bpf_attr * kattr,u32 size,u32 headroom,u32 tailroom)178 static void *bpf_test_init(const union bpf_attr *kattr, u32 size,
179 			   u32 headroom, u32 tailroom)
180 {
181 	void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
182 	u32 user_size = kattr->test.data_size_in;
183 	void *data;
184 
185 	if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom)
186 		return ERR_PTR(-EINVAL);
187 
188 	if (user_size > size)
189 		return ERR_PTR(-EMSGSIZE);
190 
191 	data = kzalloc(size + headroom + tailroom, GFP_USER);
192 	if (!data)
193 		return ERR_PTR(-ENOMEM);
194 
195 	if (copy_from_user(data + headroom, data_in, user_size)) {
196 		kfree(data);
197 		return ERR_PTR(-EFAULT);
198 	}
199 
200 	return data;
201 }
202 
bpf_prog_test_run_tracing(struct bpf_prog * prog,const union bpf_attr * kattr,union bpf_attr __user * uattr)203 int bpf_prog_test_run_tracing(struct bpf_prog *prog,
204 			      const union bpf_attr *kattr,
205 			      union bpf_attr __user *uattr)
206 {
207 	struct bpf_fentry_test_t arg = {};
208 	u16 side_effect = 0, ret = 0;
209 	int b = 2, err = -EFAULT;
210 	u32 retval = 0;
211 
212 	if (kattr->test.flags || kattr->test.cpu)
213 		return -EINVAL;
214 
215 	switch (prog->expected_attach_type) {
216 	case BPF_TRACE_FENTRY:
217 	case BPF_TRACE_FEXIT:
218 		if (bpf_fentry_test1(1) != 2 ||
219 		    bpf_fentry_test2(2, 3) != 5 ||
220 		    bpf_fentry_test3(4, 5, 6) != 15 ||
221 		    bpf_fentry_test4((void *)7, 8, 9, 10) != 34 ||
222 		    bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 ||
223 		    bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111 ||
224 		    bpf_fentry_test7((struct bpf_fentry_test_t *)0) != 0 ||
225 		    bpf_fentry_test8(&arg) != 0)
226 			goto out;
227 		break;
228 	case BPF_MODIFY_RETURN:
229 		ret = bpf_modify_return_test(1, &b);
230 		if (b != 2)
231 			side_effect = 1;
232 		break;
233 	default:
234 		goto out;
235 	}
236 
237 	retval = ((u32)side_effect << 16) | ret;
238 	if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
239 		goto out;
240 
241 	err = 0;
242 out:
243 	trace_bpf_test_finish(&err);
244 	return err;
245 }
246 
247 struct bpf_raw_tp_test_run_info {
248 	struct bpf_prog *prog;
249 	void *ctx;
250 	u32 retval;
251 };
252 
253 static void
__bpf_prog_test_run_raw_tp(void * data)254 __bpf_prog_test_run_raw_tp(void *data)
255 {
256 	struct bpf_raw_tp_test_run_info *info = data;
257 
258 	rcu_read_lock();
259 	info->retval = BPF_PROG_RUN(info->prog, info->ctx);
260 	rcu_read_unlock();
261 }
262 
bpf_prog_test_run_raw_tp(struct bpf_prog * prog,const union bpf_attr * kattr,union bpf_attr __user * uattr)263 int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
264 			     const union bpf_attr *kattr,
265 			     union bpf_attr __user *uattr)
266 {
267 	void __user *ctx_in = u64_to_user_ptr(kattr->test.ctx_in);
268 	__u32 ctx_size_in = kattr->test.ctx_size_in;
269 	struct bpf_raw_tp_test_run_info info;
270 	int cpu = kattr->test.cpu, err = 0;
271 	int current_cpu;
272 
273 	/* doesn't support data_in/out, ctx_out, duration, or repeat */
274 	if (kattr->test.data_in || kattr->test.data_out ||
275 	    kattr->test.ctx_out || kattr->test.duration ||
276 	    kattr->test.repeat)
277 		return -EINVAL;
278 
279 	if (ctx_size_in < prog->aux->max_ctx_offset ||
280 	    ctx_size_in > MAX_BPF_FUNC_ARGS * sizeof(u64))
281 		return -EINVAL;
282 
283 	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 && cpu != 0)
284 		return -EINVAL;
285 
286 	if (ctx_size_in) {
287 		info.ctx = kzalloc(ctx_size_in, GFP_USER);
288 		if (!info.ctx)
289 			return -ENOMEM;
290 		if (copy_from_user(info.ctx, ctx_in, ctx_size_in)) {
291 			err = -EFAULT;
292 			goto out;
293 		}
294 	} else {
295 		info.ctx = NULL;
296 	}
297 
298 	info.prog = prog;
299 
300 	current_cpu = get_cpu();
301 	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 ||
302 	    cpu == current_cpu) {
303 		__bpf_prog_test_run_raw_tp(&info);
304 	} else if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
305 		/* smp_call_function_single() also checks cpu_online()
306 		 * after csd_lock(). However, since cpu is from user
307 		 * space, let's do an extra quick check to filter out
308 		 * invalid value before smp_call_function_single().
309 		 */
310 		err = -ENXIO;
311 	} else {
312 		err = smp_call_function_single(cpu, __bpf_prog_test_run_raw_tp,
313 					       &info, 1);
314 	}
315 	put_cpu();
316 
317 	if (!err &&
318 	    copy_to_user(&uattr->test.retval, &info.retval, sizeof(u32)))
319 		err = -EFAULT;
320 
321 out:
322 	kfree(info.ctx);
323 	return err;
324 }
325 
bpf_ctx_init(const union bpf_attr * kattr,u32 max_size)326 static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size)
327 {
328 	void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in);
329 	void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
330 	u32 size = kattr->test.ctx_size_in;
331 	void *data;
332 	int err;
333 
334 	if (!data_in && !data_out)
335 		return NULL;
336 
337 	data = kzalloc(max_size, GFP_USER);
338 	if (!data)
339 		return ERR_PTR(-ENOMEM);
340 
341 	if (data_in) {
342 		err = bpf_check_uarg_tail_zero(data_in, max_size, size);
343 		if (err) {
344 			kfree(data);
345 			return ERR_PTR(err);
346 		}
347 
348 		size = min_t(u32, max_size, size);
349 		if (copy_from_user(data, data_in, size)) {
350 			kfree(data);
351 			return ERR_PTR(-EFAULT);
352 		}
353 	}
354 	return data;
355 }
356 
bpf_ctx_finish(const union bpf_attr * kattr,union bpf_attr __user * uattr,const void * data,u32 size)357 static int bpf_ctx_finish(const union bpf_attr *kattr,
358 			  union bpf_attr __user *uattr, const void *data,
359 			  u32 size)
360 {
361 	void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
362 	int err = -EFAULT;
363 	u32 copy_size = size;
364 
365 	if (!data || !data_out)
366 		return 0;
367 
368 	if (copy_size > kattr->test.ctx_size_out) {
369 		copy_size = kattr->test.ctx_size_out;
370 		err = -ENOSPC;
371 	}
372 
373 	if (copy_to_user(data_out, data, copy_size))
374 		goto out;
375 	if (copy_to_user(&uattr->test.ctx_size_out, &size, sizeof(size)))
376 		goto out;
377 	if (err != -ENOSPC)
378 		err = 0;
379 out:
380 	return err;
381 }
382 
383 /**
384  * range_is_zero - test whether buffer is initialized
385  * @buf: buffer to check
386  * @from: check from this position
387  * @to: check up until (excluding) this position
388  *
389  * This function returns true if the there is a non-zero byte
390  * in the buf in the range [from,to).
391  */
range_is_zero(void * buf,size_t from,size_t to)392 static inline bool range_is_zero(void *buf, size_t from, size_t to)
393 {
394 	return !memchr_inv((u8 *)buf + from, 0, to - from);
395 }
396 
convert___skb_to_skb(struct sk_buff * skb,struct __sk_buff * __skb)397 static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
398 {
399 	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
400 
401 	if (!__skb)
402 		return 0;
403 
404 	/* make sure the fields we don't use are zeroed */
405 	if (!range_is_zero(__skb, 0, offsetof(struct __sk_buff, mark)))
406 		return -EINVAL;
407 
408 	/* mark is allowed */
409 
410 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, mark),
411 			   offsetof(struct __sk_buff, priority)))
412 		return -EINVAL;
413 
414 	/* priority is allowed */
415 
416 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, priority),
417 			   offsetof(struct __sk_buff, ifindex)))
418 		return -EINVAL;
419 
420 	/* ifindex is allowed */
421 
422 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, ifindex),
423 			   offsetof(struct __sk_buff, cb)))
424 		return -EINVAL;
425 
426 	/* cb is allowed */
427 
428 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, cb),
429 			   offsetof(struct __sk_buff, tstamp)))
430 		return -EINVAL;
431 
432 	/* tstamp is allowed */
433 	/* wire_len is allowed */
434 	/* gso_segs is allowed */
435 
436 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, gso_segs),
437 			   offsetof(struct __sk_buff, gso_size)))
438 		return -EINVAL;
439 
440 	/* gso_size is allowed */
441 
442 	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, gso_size),
443 			   sizeof(struct __sk_buff)))
444 		return -EINVAL;
445 
446 	skb->mark = __skb->mark;
447 	skb->priority = __skb->priority;
448 	skb->tstamp = __skb->tstamp;
449 	memcpy(&cb->data, __skb->cb, QDISC_CB_PRIV_LEN);
450 
451 	if (__skb->wire_len == 0) {
452 		cb->pkt_len = skb->len;
453 	} else {
454 		if (__skb->wire_len < skb->len ||
455 		    __skb->wire_len > GSO_MAX_SIZE)
456 			return -EINVAL;
457 		cb->pkt_len = __skb->wire_len;
458 	}
459 
460 	if (__skb->gso_segs > GSO_MAX_SEGS)
461 		return -EINVAL;
462 	skb_shinfo(skb)->gso_segs = __skb->gso_segs;
463 	skb_shinfo(skb)->gso_size = __skb->gso_size;
464 
465 	return 0;
466 }
467 
convert_skb_to___skb(struct sk_buff * skb,struct __sk_buff * __skb)468 static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb)
469 {
470 	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
471 
472 	if (!__skb)
473 		return;
474 
475 	__skb->mark = skb->mark;
476 	__skb->priority = skb->priority;
477 	__skb->ifindex = skb->dev->ifindex;
478 	__skb->tstamp = skb->tstamp;
479 	memcpy(__skb->cb, &cb->data, QDISC_CB_PRIV_LEN);
480 	__skb->wire_len = cb->pkt_len;
481 	__skb->gso_segs = skb_shinfo(skb)->gso_segs;
482 }
483 
484 static struct proto bpf_dummy_proto = {
485 	.name   = "bpf_dummy",
486 	.owner  = THIS_MODULE,
487 	.obj_size = sizeof(struct sock),
488 };
489 
bpf_prog_test_run_skb(struct bpf_prog * prog,const union bpf_attr * kattr,union bpf_attr __user * uattr)490 int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
491 			  union bpf_attr __user *uattr)
492 {
493 	bool is_l2 = false, is_direct_pkt_access = false;
494 	struct net *net = current->nsproxy->net_ns;
495 	struct net_device *dev = net->loopback_dev;
496 	u32 size = kattr->test.data_size_in;
497 	u32 repeat = kattr->test.repeat;
498 	struct __sk_buff *ctx = NULL;
499 	u32 retval, duration;
500 	int hh_len = ETH_HLEN;
501 	struct sk_buff *skb;
502 	struct sock *sk;
503 	void *data;
504 	int ret;
505 
506 	if (kattr->test.flags || kattr->test.cpu)
507 		return -EINVAL;
508 
509 	data = bpf_test_init(kattr, size, NET_SKB_PAD + NET_IP_ALIGN,
510 			     SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
511 	if (IS_ERR(data))
512 		return PTR_ERR(data);
513 
514 	ctx = bpf_ctx_init(kattr, sizeof(struct __sk_buff));
515 	if (IS_ERR(ctx)) {
516 		kfree(data);
517 		return PTR_ERR(ctx);
518 	}
519 
520 	switch (prog->type) {
521 	case BPF_PROG_TYPE_SCHED_CLS:
522 	case BPF_PROG_TYPE_SCHED_ACT:
523 		is_l2 = true;
524 		fallthrough;
525 	case BPF_PROG_TYPE_LWT_IN:
526 	case BPF_PROG_TYPE_LWT_OUT:
527 	case BPF_PROG_TYPE_LWT_XMIT:
528 		is_direct_pkt_access = true;
529 		break;
530 	default:
531 		break;
532 	}
533 
534 	sk = sk_alloc(net, AF_UNSPEC, GFP_USER, &bpf_dummy_proto, 1);
535 	if (!sk) {
536 		kfree(data);
537 		kfree(ctx);
538 		return -ENOMEM;
539 	}
540 	sock_init_data(NULL, sk);
541 
542 	skb = build_skb(data, 0);
543 	if (!skb) {
544 		kfree(data);
545 		kfree(ctx);
546 		sk_free(sk);
547 		return -ENOMEM;
548 	}
549 	skb->sk = sk;
550 
551 	skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
552 	__skb_put(skb, size);
553 	if (ctx && ctx->ifindex > 1) {
554 		dev = dev_get_by_index(net, ctx->ifindex);
555 		if (!dev) {
556 			ret = -ENODEV;
557 			goto out;
558 		}
559 	}
560 	skb->protocol = eth_type_trans(skb, dev);
561 	skb_reset_network_header(skb);
562 
563 	switch (skb->protocol) {
564 	case htons(ETH_P_IP):
565 		sk->sk_family = AF_INET;
566 		if (sizeof(struct iphdr) <= skb_headlen(skb)) {
567 			sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
568 			sk->sk_daddr = ip_hdr(skb)->daddr;
569 		}
570 		break;
571 #if IS_ENABLED(CONFIG_IPV6)
572 	case htons(ETH_P_IPV6):
573 		sk->sk_family = AF_INET6;
574 		if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
575 			sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
576 			sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
577 		}
578 		break;
579 #endif
580 	default:
581 		break;
582 	}
583 
584 	if (is_l2)
585 		__skb_push(skb, hh_len);
586 	if (is_direct_pkt_access)
587 		bpf_compute_data_pointers(skb);
588 	ret = convert___skb_to_skb(skb, ctx);
589 	if (ret)
590 		goto out;
591 	ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
592 	if (ret)
593 		goto out;
594 	if (!is_l2) {
595 		if (skb_headroom(skb) < hh_len) {
596 			int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb));
597 
598 			if (pskb_expand_head(skb, nhead, 0, GFP_USER)) {
599 				ret = -ENOMEM;
600 				goto out;
601 			}
602 		}
603 		memset(__skb_push(skb, hh_len), 0, hh_len);
604 	}
605 	convert_skb_to___skb(skb, ctx);
606 
607 	size = skb->len;
608 	/* bpf program can never convert linear skb to non-linear */
609 	if (WARN_ON_ONCE(skb_is_nonlinear(skb)))
610 		size = skb_headlen(skb);
611 	ret = bpf_test_finish(kattr, uattr, skb->data, size, retval, duration);
612 	if (!ret)
613 		ret = bpf_ctx_finish(kattr, uattr, ctx,
614 				     sizeof(struct __sk_buff));
615 out:
616 	if (dev && dev != net->loopback_dev)
617 		dev_put(dev);
618 	kfree_skb(skb);
619 	sk_free(sk);
620 	kfree(ctx);
621 	return ret;
622 }
623 
bpf_prog_test_run_xdp(struct bpf_prog * prog,const union bpf_attr * kattr,union bpf_attr __user * uattr)624 int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
625 			  union bpf_attr __user *uattr)
626 {
627 	u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
628 	u32 headroom = XDP_PACKET_HEADROOM;
629 	u32 size = kattr->test.data_size_in;
630 	u32 repeat = kattr->test.repeat;
631 	struct netdev_rx_queue *rxqueue;
632 	struct xdp_buff xdp = {};
633 	u32 retval, duration;
634 	u32 max_data_sz;
635 	void *data;
636 	int ret;
637 
638 	if (prog->expected_attach_type == BPF_XDP_DEVMAP ||
639 	    prog->expected_attach_type == BPF_XDP_CPUMAP)
640 		return -EINVAL;
641 	if (kattr->test.ctx_in || kattr->test.ctx_out)
642 		return -EINVAL;
643 
644 	/* XDP have extra tailroom as (most) drivers use full page */
645 	max_data_sz = 4096 - headroom - tailroom;
646 
647 	data = bpf_test_init(kattr, max_data_sz, headroom, tailroom);
648 	if (IS_ERR(data))
649 		return PTR_ERR(data);
650 
651 	xdp.data_hard_start = data;
652 	xdp.data = data + headroom;
653 	xdp.data_meta = xdp.data;
654 	xdp.data_end = xdp.data + size;
655 	xdp.frame_sz = headroom + max_data_sz + tailroom;
656 
657 	rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
658 	xdp.rxq = &rxqueue->xdp_rxq;
659 	bpf_prog_change_xdp(NULL, prog);
660 	ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true);
661 	if (ret)
662 		goto out;
663 	if (xdp.data != data + headroom || xdp.data_end != xdp.data + size)
664 		size = xdp.data_end - xdp.data;
665 	ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
666 out:
667 	bpf_prog_change_xdp(prog, NULL);
668 	kfree(data);
669 	return ret;
670 }
671 
verify_user_bpf_flow_keys(struct bpf_flow_keys * ctx)672 static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx)
673 {
674 	/* make sure the fields we don't use are zeroed */
675 	if (!range_is_zero(ctx, 0, offsetof(struct bpf_flow_keys, flags)))
676 		return -EINVAL;
677 
678 	/* flags is allowed */
679 
680 	if (!range_is_zero(ctx, offsetofend(struct bpf_flow_keys, flags),
681 			   sizeof(struct bpf_flow_keys)))
682 		return -EINVAL;
683 
684 	return 0;
685 }
686 
bpf_prog_test_run_flow_dissector(struct bpf_prog * prog,const union bpf_attr * kattr,union bpf_attr __user * uattr)687 int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
688 				     const union bpf_attr *kattr,
689 				     union bpf_attr __user *uattr)
690 {
691 	u32 size = kattr->test.data_size_in;
692 	struct bpf_flow_dissector ctx = {};
693 	u32 repeat = kattr->test.repeat;
694 	struct bpf_flow_keys *user_ctx;
695 	struct bpf_flow_keys flow_keys;
696 	u64 time_start, time_spent = 0;
697 	const struct ethhdr *eth;
698 	unsigned int flags = 0;
699 	u32 retval, duration;
700 	void *data;
701 	int ret;
702 	u32 i;
703 
704 	if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR)
705 		return -EINVAL;
706 
707 	if (kattr->test.flags || kattr->test.cpu)
708 		return -EINVAL;
709 
710 	if (size < ETH_HLEN)
711 		return -EINVAL;
712 
713 	data = bpf_test_init(kattr, size, 0, 0);
714 	if (IS_ERR(data))
715 		return PTR_ERR(data);
716 
717 	eth = (struct ethhdr *)data;
718 
719 	if (!repeat)
720 		repeat = 1;
721 
722 	user_ctx = bpf_ctx_init(kattr, sizeof(struct bpf_flow_keys));
723 	if (IS_ERR(user_ctx)) {
724 		kfree(data);
725 		return PTR_ERR(user_ctx);
726 	}
727 	if (user_ctx) {
728 		ret = verify_user_bpf_flow_keys(user_ctx);
729 		if (ret)
730 			goto out;
731 		flags = user_ctx->flags;
732 	}
733 
734 	ctx.flow_keys = &flow_keys;
735 	ctx.data = data;
736 	ctx.data_end = (__u8 *)data + size;
737 
738 	rcu_read_lock();
739 	preempt_disable();
740 	time_start = ktime_get_ns();
741 	for (i = 0; i < repeat; i++) {
742 		retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
743 					  size, flags);
744 
745 		if (signal_pending(current)) {
746 			preempt_enable();
747 			rcu_read_unlock();
748 
749 			ret = -EINTR;
750 			goto out;
751 		}
752 
753 		if (need_resched()) {
754 			time_spent += ktime_get_ns() - time_start;
755 			preempt_enable();
756 			rcu_read_unlock();
757 
758 			cond_resched();
759 
760 			rcu_read_lock();
761 			preempt_disable();
762 			time_start = ktime_get_ns();
763 		}
764 	}
765 	time_spent += ktime_get_ns() - time_start;
766 	preempt_enable();
767 	rcu_read_unlock();
768 
769 	do_div(time_spent, repeat);
770 	duration = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
771 
772 	ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys),
773 			      retval, duration);
774 	if (!ret)
775 		ret = bpf_ctx_finish(kattr, uattr, user_ctx,
776 				     sizeof(struct bpf_flow_keys));
777 
778 out:
779 	kfree(user_ctx);
780 	kfree(data);
781 	return ret;
782 }
783