test_run.c 22.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
2 3 4
/* Copyright (c) 2017 Facebook
 */
#include <linux/bpf.h>
5
#include <linux/btf_ids.h>
6 7 8 9 10
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/etherdevice.h>
#include <linux/filter.h>
#include <linux/sched/signal.h>
11
#include <net/bpf_sk_storage.h>
12 13
#include <net/sock.h>
#include <net/tcp.h>
14
#include <net/net_namespace.h>
15
#include <linux/error-injection.h>
16
#include <linux/smp.h>
17
#include <linux/sock_diag.h>
18

19 20 21
#define CREATE_TRACE_POINTS
#include <trace/events/bpf_test_run.h>

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
struct bpf_test_timer {
	enum { NO_PREEMPT, NO_MIGRATE } mode;
	u32 i;
	u64 time_start, time_spent;
};

static void bpf_test_timer_enter(struct bpf_test_timer *t)
	__acquires(rcu)
{
	rcu_read_lock();
	if (t->mode == NO_PREEMPT)
		preempt_disable();
	else
		migrate_disable();

	t->time_start = ktime_get_ns();
}

static void bpf_test_timer_leave(struct bpf_test_timer *t)
	__releases(rcu)
{
	t->time_start = 0;

	if (t->mode == NO_PREEMPT)
		preempt_enable();
	else
		migrate_enable();
	rcu_read_unlock();
}

static bool bpf_test_timer_continue(struct bpf_test_timer *t, u32 repeat, int *err, u32 *duration)
	__must_hold(rcu)
{
	t->i++;
	if (t->i >= repeat) {
		/* We're done. */
		t->time_spent += ktime_get_ns() - t->time_start;
		do_div(t->time_spent, t->i);
		*duration = t->time_spent > U32_MAX ? U32_MAX : (u32)t->time_spent;
		*err = 0;
		goto reset;
	}

	if (signal_pending(current)) {
		/* During iteration: we've been cancelled, abort. */
		*err = -EINTR;
		goto reset;
	}

	if (need_resched()) {
		/* During iteration: we need to reschedule between runs. */
		t->time_spent += ktime_get_ns() - t->time_start;
		bpf_test_timer_leave(t);
		cond_resched();
		bpf_test_timer_enter(t);
	}

	/* Do another round. */
	return true;

reset:
	t->i = 0;
	return false;
}

87
static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
88
			u32 *retval, u32 *time, bool xdp)
89
{
90
	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { NULL };
91
	struct bpf_test_timer t = { NO_MIGRATE };
92
	enum bpf_cgroup_storage_type stype;
93
	int ret;
94

95 96 97 98 99 100 101 102 103
	for_each_cgroup_storage_type(stype) {
		storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
		if (IS_ERR(storage[stype])) {
			storage[stype] = NULL;
			for_each_cgroup_storage_type(stype)
				bpf_cgroup_storage_free(storage[stype]);
			return -ENOMEM;
		}
	}
104

105 106
	if (!repeat)
		repeat = 1;
107

108 109
	bpf_test_timer_enter(&t);
	do {
110 111 112
		ret = bpf_cgroup_storage_set(storage);
		if (ret)
			break;
113 114 115 116 117

		if (xdp)
			*retval = bpf_prog_run_xdp(prog, ctx);
		else
			*retval = BPF_PROG_RUN(prog, ctx);
118 119

		bpf_cgroup_storage_unset();
120 121
	} while (bpf_test_timer_continue(&t, repeat, &ret, time));
	bpf_test_timer_leave(&t);
122

123 124
	for_each_cgroup_storage_type(stype)
		bpf_cgroup_storage_free(storage[stype]);
125

126
	return ret;
127 128
}

129 130
static int bpf_test_finish(const union bpf_attr *kattr,
			   union bpf_attr __user *uattr, const void *data,
131 132
			   u32 size, u32 retval, u32 duration)
{
133
	void __user *data_out = u64_to_user_ptr(kattr->test.data_out);
134
	int err = -EFAULT;
135
	u32 copy_size = size;
136

137 138 139 140 141 142 143 144 145 146
	/* Clamp copy if the user has provided a size hint, but copy the full
	 * buffer if not to retain old behaviour.
	 */
	if (kattr->test.data_size_out &&
	    copy_size > kattr->test.data_size_out) {
		copy_size = kattr->test.data_size_out;
		err = -ENOSPC;
	}

	if (data_out && copy_to_user(data_out, data, copy_size))
147 148 149 150 151 152 153
		goto out;
	if (copy_to_user(&uattr->test.data_size_out, &size, sizeof(size)))
		goto out;
	if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
		goto out;
	if (copy_to_user(&uattr->test.duration, &duration, sizeof(duration)))
		goto out;
154 155
	if (err != -ENOSPC)
		err = 0;
156
out:
157
	trace_bpf_test_finish(&err);
158 159 160
	return err;
}

161 162 163 164
/* Integer types of various sizes and pointer combinations cover variety of
 * architecture dependent calling conventions. 7+ can be supported in the
 * future.
 */
165 166 167
__diag_push();
__diag_ignore(GCC, 8, "-Wmissing-prototypes",
	      "Global functions as their definitions will be in vmlinux BTF");
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
int noinline bpf_fentry_test1(int a)
{
	return a + 1;
}

int noinline bpf_fentry_test2(int a, u64 b)
{
	return a + b;
}

int noinline bpf_fentry_test3(char a, int b, u64 c)
{
	return a + b + c;
}

int noinline bpf_fentry_test4(void *a, char b, int c, u64 d)
{
	return (long)a + b + c + d;
}

int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e)
{
	return a + (long)b + c + d + e;
}

int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f)
{
	return a + (long)b + c + d + (long)e + f;
}

198 199 200 201 202 203 204 205 206 207 208 209 210 211
struct bpf_fentry_test_t {
	struct bpf_fentry_test_t *a;
};

int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg)
{
	return (long)arg;
}

int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg)
{
	return (long)arg->a;
}

212 213 214 215 216
int noinline bpf_modify_return_test(int a, int *b)
{
	*b += 1;
	return a + *b;
}
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

u64 noinline bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d)
{
	return a + b + c + d;
}

int noinline bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b)
{
	return a + b;
}

struct sock * noinline bpf_kfunc_call_test3(struct sock *sk)
{
	return sk;
}

233
__diag_pop();
234 235 236

ALLOW_ERROR_INJECTION(bpf_modify_return_test, ERRNO);

237 238 239 240 241 242 243 244 245 246 247
BTF_SET_START(test_sk_kfunc_ids)
BTF_ID(func, bpf_kfunc_call_test1)
BTF_ID(func, bpf_kfunc_call_test2)
BTF_ID(func, bpf_kfunc_call_test3)
BTF_SET_END(test_sk_kfunc_ids)

bool bpf_prog_test_check_kfunc_call(u32 kfunc_id)
{
	return btf_id_set_contains(&test_sk_kfunc_ids, kfunc_id);
}

248 249 250 251
static void *bpf_test_init(const union bpf_attr *kattr, u32 size,
			   u32 headroom, u32 tailroom)
{
	void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
252
	u32 user_size = kattr->test.data_size_in;
253 254 255 256 257
	void *data;

	if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom)
		return ERR_PTR(-EINVAL);

258 259 260
	if (user_size > size)
		return ERR_PTR(-EMSGSIZE);

261 262 263 264
	data = kzalloc(size + headroom + tailroom, GFP_USER);
	if (!data)
		return ERR_PTR(-ENOMEM);

265
	if (copy_from_user(data + headroom, data_in, user_size)) {
266 267 268
		kfree(data);
		return ERR_PTR(-EFAULT);
	}
269

270 271 272
	return data;
}

273 274 275 276
int bpf_prog_test_run_tracing(struct bpf_prog *prog,
			      const union bpf_attr *kattr,
			      union bpf_attr __user *uattr)
{
277
	struct bpf_fentry_test_t arg = {};
278 279 280
	u16 side_effect = 0, ret = 0;
	int b = 2, err = -EFAULT;
	u32 retval = 0;
281

282 283 284
	if (kattr->test.flags || kattr->test.cpu)
		return -EINVAL;

285 286 287 288 289 290 291 292
	switch (prog->expected_attach_type) {
	case BPF_TRACE_FENTRY:
	case BPF_TRACE_FEXIT:
		if (bpf_fentry_test1(1) != 2 ||
		    bpf_fentry_test2(2, 3) != 5 ||
		    bpf_fentry_test3(4, 5, 6) != 15 ||
		    bpf_fentry_test4((void *)7, 8, 9, 10) != 34 ||
		    bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 ||
293 294 295
		    bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111 ||
		    bpf_fentry_test7((struct bpf_fentry_test_t *)0) != 0 ||
		    bpf_fentry_test8(&arg) != 0)
296 297
			goto out;
		break;
298 299 300 301 302
	case BPF_MODIFY_RETURN:
		ret = bpf_modify_return_test(1, &b);
		if (b != 2)
			side_effect = 1;
		break;
303 304 305 306
	default:
		goto out;
	}

307 308 309 310
	retval = ((u32)side_effect << 16) | ret;
	if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
		goto out;

311 312 313 314 315 316
	err = 0;
out:
	trace_bpf_test_finish(&err);
	return err;
}

317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
struct bpf_raw_tp_test_run_info {
	struct bpf_prog *prog;
	void *ctx;
	u32 retval;
};

static void
__bpf_prog_test_run_raw_tp(void *data)
{
	struct bpf_raw_tp_test_run_info *info = data;

	rcu_read_lock();
	info->retval = BPF_PROG_RUN(info->prog, info->ctx);
	rcu_read_unlock();
}

int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
			     const union bpf_attr *kattr,
			     union bpf_attr __user *uattr)
{
	void __user *ctx_in = u64_to_user_ptr(kattr->test.ctx_in);
	__u32 ctx_size_in = kattr->test.ctx_size_in;
	struct bpf_raw_tp_test_run_info info;
	int cpu = kattr->test.cpu, err = 0;
341
	int current_cpu;
342 343 344 345 346 347 348

	/* doesn't support data_in/out, ctx_out, duration, or repeat */
	if (kattr->test.data_in || kattr->test.data_out ||
	    kattr->test.ctx_out || kattr->test.duration ||
	    kattr->test.repeat)
		return -EINVAL;

349 350
	if (ctx_size_in < prog->aux->max_ctx_offset ||
	    ctx_size_in > MAX_BPF_FUNC_ARGS * sizeof(u64))
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
		return -EINVAL;

	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 && cpu != 0)
		return -EINVAL;

	if (ctx_size_in) {
		info.ctx = kzalloc(ctx_size_in, GFP_USER);
		if (!info.ctx)
			return -ENOMEM;
		if (copy_from_user(info.ctx, ctx_in, ctx_size_in)) {
			err = -EFAULT;
			goto out;
		}
	} else {
		info.ctx = NULL;
	}

	info.prog = prog;

370
	current_cpu = get_cpu();
371
	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 ||
372
	    cpu == current_cpu) {
373
		__bpf_prog_test_run_raw_tp(&info);
374
	} else if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
375 376 377 378 379
		/* smp_call_function_single() also checks cpu_online()
		 * after csd_lock(). However, since cpu is from user
		 * space, let's do an extra quick check to filter out
		 * invalid value before smp_call_function_single().
		 */
380 381
		err = -ENXIO;
	} else {
382 383 384
		err = smp_call_function_single(cpu, __bpf_prog_test_run_raw_tp,
					       &info, 1);
	}
385
	put_cpu();
386

387 388
	if (!err &&
	    copy_to_user(&uattr->test.retval, &info.retval, sizeof(u32)))
389 390 391 392 393 394 395
		err = -EFAULT;

out:
	kfree(info.ctx);
	return err;
}

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size)
{
	void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in);
	void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
	u32 size = kattr->test.ctx_size_in;
	void *data;
	int err;

	if (!data_in && !data_out)
		return NULL;

	data = kzalloc(max_size, GFP_USER);
	if (!data)
		return ERR_PTR(-ENOMEM);

	if (data_in) {
412
		err = bpf_check_uarg_tail_zero(USER_BPFPTR(data_in), max_size, size);
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
		if (err) {
			kfree(data);
			return ERR_PTR(err);
		}

		size = min_t(u32, max_size, size);
		if (copy_from_user(data, data_in, size)) {
			kfree(data);
			return ERR_PTR(-EFAULT);
		}
	}
	return data;
}

static int bpf_ctx_finish(const union bpf_attr *kattr,
			  union bpf_attr __user *uattr, const void *data,
			  u32 size)
{
	void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
	int err = -EFAULT;
	u32 copy_size = size;

	if (!data || !data_out)
		return 0;

	if (copy_size > kattr->test.ctx_size_out) {
		copy_size = kattr->test.ctx_size_out;
		err = -ENOSPC;
	}

	if (copy_to_user(data_out, data, copy_size))
		goto out;
	if (copy_to_user(&uattr->test.ctx_size_out, &size, sizeof(size)))
		goto out;
	if (err != -ENOSPC)
		err = 0;
out:
	return err;
}

/**
 * range_is_zero - test whether buffer is initialized
 * @buf: buffer to check
 * @from: check from this position
 * @to: check up until (excluding) this position
 *
 * This function returns true if the there is a non-zero byte
 * in the buf in the range [from,to).
 */
static inline bool range_is_zero(void *buf, size_t from, size_t to)
{
	return !memchr_inv((u8 *)buf + from, 0, to - from);
}

static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
{
	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;

	if (!__skb)
		return 0;

	/* make sure the fields we don't use are zeroed */
475 476 477 478 479 480 481
	if (!range_is_zero(__skb, 0, offsetof(struct __sk_buff, mark)))
		return -EINVAL;

	/* mark is allowed */

	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, mark),
			   offsetof(struct __sk_buff, priority)))
482 483 484 485
		return -EINVAL;

	/* priority is allowed */

486
	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, priority),
487 488 489 490 491 492
			   offsetof(struct __sk_buff, ifindex)))
		return -EINVAL;

	/* ifindex is allowed */

	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, ifindex),
493 494 495 496 497
			   offsetof(struct __sk_buff, cb)))
		return -EINVAL;

	/* cb is allowed */

498
	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, cb),
499 500 501 502
			   offsetof(struct __sk_buff, tstamp)))
		return -EINVAL;

	/* tstamp is allowed */
503 504
	/* wire_len is allowed */
	/* gso_segs is allowed */
505

506
	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, gso_segs),
507 508 509 510 511 512
			   offsetof(struct __sk_buff, gso_size)))
		return -EINVAL;

	/* gso_size is allowed */

	if (!range_is_zero(__skb, offsetofend(struct __sk_buff, gso_size),
513 514 515
			   sizeof(struct __sk_buff)))
		return -EINVAL;

516
	skb->mark = __skb->mark;
517
	skb->priority = __skb->priority;
518
	skb->tstamp = __skb->tstamp;
519 520
	memcpy(&cb->data, __skb->cb, QDISC_CB_PRIV_LEN);

521 522 523 524 525 526 527 528 529 530 531 532
	if (__skb->wire_len == 0) {
		cb->pkt_len = skb->len;
	} else {
		if (__skb->wire_len < skb->len ||
		    __skb->wire_len > GSO_MAX_SIZE)
			return -EINVAL;
		cb->pkt_len = __skb->wire_len;
	}

	if (__skb->gso_segs > GSO_MAX_SEGS)
		return -EINVAL;
	skb_shinfo(skb)->gso_segs = __skb->gso_segs;
533
	skb_shinfo(skb)->gso_size = __skb->gso_size;
534

535 536 537 538 539 540 541 542 543 544
	return 0;
}

static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb)
{
	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;

	if (!__skb)
		return;

545
	__skb->mark = skb->mark;
546
	__skb->priority = skb->priority;
547
	__skb->ifindex = skb->dev->ifindex;
548
	__skb->tstamp = skb->tstamp;
549
	memcpy(__skb->cb, &cb->data, QDISC_CB_PRIV_LEN);
550 551
	__skb->wire_len = cb->pkt_len;
	__skb->gso_segs = skb_shinfo(skb)->gso_segs;
552 553
}

554 555 556 557
int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
			  union bpf_attr __user *uattr)
{
	bool is_l2 = false, is_direct_pkt_access = false;
558 559
	struct net *net = current->nsproxy->net_ns;
	struct net_device *dev = net->loopback_dev;
560 561
	u32 size = kattr->test.data_size_in;
	u32 repeat = kattr->test.repeat;
562
	struct __sk_buff *ctx = NULL;
563
	u32 retval, duration;
564
	int hh_len = ETH_HLEN;
565
	struct sk_buff *skb;
566
	struct sock *sk;
567 568 569
	void *data;
	int ret;

570 571 572
	if (kattr->test.flags || kattr->test.cpu)
		return -EINVAL;

573
	data = bpf_test_init(kattr, size, NET_SKB_PAD + NET_IP_ALIGN,
574 575 576 577
			     SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
	if (IS_ERR(data))
		return PTR_ERR(data);

578 579 580 581 582 583
	ctx = bpf_ctx_init(kattr, sizeof(struct __sk_buff));
	if (IS_ERR(ctx)) {
		kfree(data);
		return PTR_ERR(ctx);
	}

584 585 586 587
	switch (prog->type) {
	case BPF_PROG_TYPE_SCHED_CLS:
	case BPF_PROG_TYPE_SCHED_ACT:
		is_l2 = true;
588
		fallthrough;
589 590 591 592 593 594 595 596 597
	case BPF_PROG_TYPE_LWT_IN:
	case BPF_PROG_TYPE_LWT_OUT:
	case BPF_PROG_TYPE_LWT_XMIT:
		is_direct_pkt_access = true;
		break;
	default:
		break;
	}

598 599 600
	sk = kzalloc(sizeof(struct sock), GFP_USER);
	if (!sk) {
		kfree(data);
601
		kfree(ctx);
602 603
		return -ENOMEM;
	}
604
	sock_net_set(sk, net);
605 606
	sock_init_data(NULL, sk);

607 608 609
	skb = build_skb(data, 0);
	if (!skb) {
		kfree(data);
610
		kfree(ctx);
611
		kfree(sk);
612 613
		return -ENOMEM;
	}
614
	skb->sk = sk;
615

616
	skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
617
	__skb_put(skb, size);
618 619 620 621 622 623 624 625
	if (ctx && ctx->ifindex > 1) {
		dev = dev_get_by_index(net, ctx->ifindex);
		if (!dev) {
			ret = -ENODEV;
			goto out;
		}
	}
	skb->protocol = eth_type_trans(skb, dev);
626 627
	skb_reset_network_header(skb);

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
	switch (skb->protocol) {
	case htons(ETH_P_IP):
		sk->sk_family = AF_INET;
		if (sizeof(struct iphdr) <= skb_headlen(skb)) {
			sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
			sk->sk_daddr = ip_hdr(skb)->daddr;
		}
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case htons(ETH_P_IPV6):
		sk->sk_family = AF_INET6;
		if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
			sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
			sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
		}
		break;
#endif
	default:
		break;
	}

649
	if (is_l2)
650
		__skb_push(skb, hh_len);
651
	if (is_direct_pkt_access)
652
		bpf_compute_data_pointers(skb);
653 654 655
	ret = convert___skb_to_skb(skb, ctx);
	if (ret)
		goto out;
656
	ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
657 658
	if (ret)
		goto out;
659 660 661 662 663
	if (!is_l2) {
		if (skb_headroom(skb) < hh_len) {
			int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb));

			if (pskb_expand_head(skb, nhead, 0, GFP_USER)) {
664 665
				ret = -ENOMEM;
				goto out;
666 667 668 669
			}
		}
		memset(__skb_push(skb, hh_len), 0, hh_len);
	}
670
	convert_skb_to___skb(skb, ctx);
671

672 673 674 675
	size = skb->len;
	/* bpf program can never convert linear skb to non-linear */
	if (WARN_ON_ONCE(skb_is_nonlinear(skb)))
		size = skb_headlen(skb);
676
	ret = bpf_test_finish(kattr, uattr, skb->data, size, retval, duration);
677 678 679 680
	if (!ret)
		ret = bpf_ctx_finish(kattr, uattr, ctx,
				     sizeof(struct __sk_buff));
out:
681 682
	if (dev && dev != net->loopback_dev)
		dev_put(dev);
683
	kfree_skb(skb);
684
	bpf_sk_storage_free(sk);
685
	kfree(sk);
686
	kfree(ctx);
687 688 689 690 691 692
	return ret;
}

int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
			  union bpf_attr __user *uattr)
{
693 694
	u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
	u32 headroom = XDP_PACKET_HEADROOM;
695 696
	u32 size = kattr->test.data_size_in;
	u32 repeat = kattr->test.repeat;
697
	struct netdev_rx_queue *rxqueue;
698 699
	struct xdp_buff xdp = {};
	u32 retval, duration;
700
	u32 max_data_sz;
701 702 703
	void *data;
	int ret;

704 705 706
	if (prog->expected_attach_type == BPF_XDP_DEVMAP ||
	    prog->expected_attach_type == BPF_XDP_CPUMAP)
		return -EINVAL;
707 708 709
	if (kattr->test.ctx_in || kattr->test.ctx_out)
		return -EINVAL;

710 711 712 713
	/* XDP have extra tailroom as (most) drivers use full page */
	max_data_sz = 4096 - headroom - tailroom;

	data = bpf_test_init(kattr, max_data_sz, headroom, tailroom);
714 715 716
	if (IS_ERR(data))
		return PTR_ERR(data);

717
	rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
718 719
	xdp_init_buff(&xdp, headroom + max_data_sz + tailroom,
		      &rxqueue->xdp_rxq);
720 721
	xdp_prepare_buff(&xdp, data, headroom, size, true);

722 723
	bpf_prog_change_xdp(NULL, prog);
	ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true);
724 725
	if (ret)
		goto out;
726
	if (xdp.data != data + headroom || xdp.data_end != xdp.data + size)
727
		size = xdp.data_end - xdp.data;
728
	ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
729
out:
730
	bpf_prog_change_xdp(prog, NULL);
731 732 733
	kfree(data);
	return ret;
}
734

735 736 737 738 739 740 741 742
static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx)
{
	/* make sure the fields we don't use are zeroed */
	if (!range_is_zero(ctx, 0, offsetof(struct bpf_flow_keys, flags)))
		return -EINVAL;

	/* flags is allowed */

743
	if (!range_is_zero(ctx, offsetofend(struct bpf_flow_keys, flags),
744 745 746 747 748 749
			   sizeof(struct bpf_flow_keys)))
		return -EINVAL;

	return 0;
}

750 751 752 753
int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
				     const union bpf_attr *kattr,
				     union bpf_attr __user *uattr)
{
754
	struct bpf_test_timer t = { NO_PREEMPT };
755
	u32 size = kattr->test.data_size_in;
756
	struct bpf_flow_dissector ctx = {};
757
	u32 repeat = kattr->test.repeat;
758
	struct bpf_flow_keys *user_ctx;
759
	struct bpf_flow_keys flow_keys;
760
	const struct ethhdr *eth;
761
	unsigned int flags = 0;
762 763 764 765 766 767 768
	u32 retval, duration;
	void *data;
	int ret;

	if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR)
		return -EINVAL;

769 770 771
	if (kattr->test.flags || kattr->test.cpu)
		return -EINVAL;

772 773 774 775
	if (size < ETH_HLEN)
		return -EINVAL;

	data = bpf_test_init(kattr, size, 0, 0);
776 777 778
	if (IS_ERR(data))
		return PTR_ERR(data);

779
	eth = (struct ethhdr *)data;
780 781 782 783

	if (!repeat)
		repeat = 1;

784 785 786 787 788 789 790 791 792 793 794 795
	user_ctx = bpf_ctx_init(kattr, sizeof(struct bpf_flow_keys));
	if (IS_ERR(user_ctx)) {
		kfree(data);
		return PTR_ERR(user_ctx);
	}
	if (user_ctx) {
		ret = verify_user_bpf_flow_keys(user_ctx);
		if (ret)
			goto out;
		flags = user_ctx->flags;
	}

796 797 798 799
	ctx.flow_keys = &flow_keys;
	ctx.data = data;
	ctx.data_end = (__u8 *)data + size;

800 801
	bpf_test_timer_enter(&t);
	do {
802
		retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
803
					  size, flags);
804 805
	} while (bpf_test_timer_continue(&t, repeat, &ret, &duration));
	bpf_test_timer_leave(&t);
806

807 808
	if (ret < 0)
		goto out;
809 810 811

	ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys),
			      retval, duration);
812 813 814
	if (!ret)
		ret = bpf_ctx_finish(kattr, uattr, user_ctx,
				     sizeof(struct bpf_flow_keys));
815

816
out:
817
	kfree(user_ctx);
818
	kfree(data);
819 820
	return ret;
}
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923

int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog, const union bpf_attr *kattr,
				union bpf_attr __user *uattr)
{
	struct bpf_test_timer t = { NO_PREEMPT };
	struct bpf_prog_array *progs = NULL;
	struct bpf_sk_lookup_kern ctx = {};
	u32 repeat = kattr->test.repeat;
	struct bpf_sk_lookup *user_ctx;
	u32 retval, duration;
	int ret = -EINVAL;

	if (prog->type != BPF_PROG_TYPE_SK_LOOKUP)
		return -EINVAL;

	if (kattr->test.flags || kattr->test.cpu)
		return -EINVAL;

	if (kattr->test.data_in || kattr->test.data_size_in || kattr->test.data_out ||
	    kattr->test.data_size_out)
		return -EINVAL;

	if (!repeat)
		repeat = 1;

	user_ctx = bpf_ctx_init(kattr, sizeof(*user_ctx));
	if (IS_ERR(user_ctx))
		return PTR_ERR(user_ctx);

	if (!user_ctx)
		return -EINVAL;

	if (user_ctx->sk)
		goto out;

	if (!range_is_zero(user_ctx, offsetofend(typeof(*user_ctx), local_port), sizeof(*user_ctx)))
		goto out;

	if (user_ctx->local_port > U16_MAX || user_ctx->remote_port > U16_MAX) {
		ret = -ERANGE;
		goto out;
	}

	ctx.family = (u16)user_ctx->family;
	ctx.protocol = (u16)user_ctx->protocol;
	ctx.dport = (u16)user_ctx->local_port;
	ctx.sport = (__force __be16)user_ctx->remote_port;

	switch (ctx.family) {
	case AF_INET:
		ctx.v4.daddr = (__force __be32)user_ctx->local_ip4;
		ctx.v4.saddr = (__force __be32)user_ctx->remote_ip4;
		break;

#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		ctx.v6.daddr = (struct in6_addr *)user_ctx->local_ip6;
		ctx.v6.saddr = (struct in6_addr *)user_ctx->remote_ip6;
		break;
#endif

	default:
		ret = -EAFNOSUPPORT;
		goto out;
	}

	progs = bpf_prog_array_alloc(1, GFP_KERNEL);
	if (!progs) {
		ret = -ENOMEM;
		goto out;
	}

	progs->items[0].prog = prog;

	bpf_test_timer_enter(&t);
	do {
		ctx.selected_sk = NULL;
		retval = BPF_PROG_SK_LOOKUP_RUN_ARRAY(progs, ctx, BPF_PROG_RUN);
	} while (bpf_test_timer_continue(&t, repeat, &ret, &duration));
	bpf_test_timer_leave(&t);

	if (ret < 0)
		goto out;

	user_ctx->cookie = 0;
	if (ctx.selected_sk) {
		if (ctx.selected_sk->sk_reuseport && !ctx.no_reuseport) {
			ret = -EOPNOTSUPP;
			goto out;
		}

		user_ctx->cookie = sock_gen_cookie(ctx.selected_sk);
	}

	ret = bpf_test_finish(kattr, uattr, NULL, 0, retval, duration);
	if (!ret)
		ret = bpf_ctx_finish(kattr, uattr, user_ctx, sizeof(*user_ctx));

out:
	bpf_prog_array_free(progs);
	kfree(user_ctx);
	return ret;
}
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966

int bpf_prog_test_run_syscall(struct bpf_prog *prog,
			      const union bpf_attr *kattr,
			      union bpf_attr __user *uattr)
{
	void __user *ctx_in = u64_to_user_ptr(kattr->test.ctx_in);
	__u32 ctx_size_in = kattr->test.ctx_size_in;
	void *ctx = NULL;
	u32 retval;
	int err = 0;

	/* doesn't support data_in/out, ctx_out, duration, or repeat or flags */
	if (kattr->test.data_in || kattr->test.data_out ||
	    kattr->test.ctx_out || kattr->test.duration ||
	    kattr->test.repeat || kattr->test.flags)
		return -EINVAL;

	if (ctx_size_in < prog->aux->max_ctx_offset ||
	    ctx_size_in > U16_MAX)
		return -EINVAL;

	if (ctx_size_in) {
		ctx = kzalloc(ctx_size_in, GFP_USER);
		if (!ctx)
			return -ENOMEM;
		if (copy_from_user(ctx, ctx_in, ctx_size_in)) {
			err = -EFAULT;
			goto out;
		}
	}
	retval = bpf_prog_run_pin_on_cpu(prog, ctx);

	if (copy_to_user(&uattr->test.retval, &retval, sizeof(u32))) {
		err = -EFAULT;
		goto out;
	}
	if (ctx_size_in)
		if (copy_to_user(ctx_in, ctx, ctx_size_in))
			err = -EFAULT;
out:
	kfree(ctx);
	return err;
}