aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-27 15:03:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-27 15:03:20 -0400
commit468fc7ed5537615efe671d94248446ac24679773 (patch)
tree27bc9de792e863d6ec1630927b77ac9e7dabb38a /kernel/bpf
parent08fd8c17686c6b09fa410a26d516548dd80ff147 (diff)
parent36232012344b8db67052432742deaf17f82e70e6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Unified UDP encapsulation offload methods for drivers, from Alexander Duyck. 2) Make DSA binding more sane, from Andrew Lunn. 3) Support QCA9888 chips in ath10k, from Anilkumar Kolli. 4) Several workqueue usage cleanups, from Bhaktipriya Shridhar. 5) Add XDP (eXpress Data Path), essentially running BPF programs on RX packets as soon as the device sees them, with the option to mirror the packet on TX via the same interface. From Brenden Blanco and others. 6) Allow qdisc/class stats dumps to run lockless, from Eric Dumazet. 7) Add VLAN support to b53 and bcm_sf2, from Florian Fainelli. 8) Simplify netlink conntrack entry layout, from Florian Westphal. 9) Add ipv4 forwarding support to mlxsw spectrum driver, from Ido Schimmel, Yotam Gigi, and Jiri Pirko. 10) Add SKB array infrastructure and convert tun and macvtap over to it. From Michael S Tsirkin and Jason Wang. 11) Support qdisc packet injection in pktgen, from John Fastabend. 12) Add neighbour monitoring framework to TIPC, from Jon Paul Maloy. 13) Add NV congestion control support to TCP, from Lawrence Brakmo. 14) Add GSO support to SCTP, from Marcelo Ricardo Leitner. 15) Allow GRO and RPS to function on macsec devices, from Paolo Abeni. 16) Support MPLS over IPV4, from Simon Horman. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1622 commits) xgene: Fix build warning with ACPI disabled. be2net: perform temperature query in adapter regardless of its interface state l2tp: Correctly return -EBADF from pppol2tp_getname. net/mlx5_core/health: Remove deprecated create_singlethread_workqueue net: ipmr/ip6mr: update lastuse on entry change macsec: ensure rx_sa is set when validation is disabled tipc: dump monitor attributes tipc: add a function to get the bearer name tipc: get monitor threshold for the cluster tipc: make cluster size threshold for monitoring configurable tipc: introduce constants for tipc address validation net: neigh: disallow transition to NUD_STALE if lladdr is unchanged in neigh_update() MAINTAINERS: xgene: Add driver and documentation path Documentation: dtb: xgene: Add MDIO node dtb: xgene: Add MDIO node drivers: net: xgene: ethtool: Use phy_ethtool_gset and sset drivers: net: xgene: Use exported functions drivers: net: xgene: Enable MDIO driver drivers: net: xgene: Add backward compatibility drivers: net: phy: xgene: Add MDIO driver ...
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/arraymap.c163
-rw-r--r--kernel/bpf/core.c9
-rw-r--r--kernel/bpf/helpers.c2
-rw-r--r--kernel/bpf/inode.c4
-rw-r--r--kernel/bpf/syscall.c66
-rw-r--r--kernel/bpf/verifier.c26
6 files changed, 202 insertions, 68 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 76d5a794e426..633a650d7aeb 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -328,8 +328,8 @@ static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key)
328} 328}
329 329
330/* only called from syscall */ 330/* only called from syscall */
331static int fd_array_map_update_elem(struct bpf_map *map, void *key, 331int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
332 void *value, u64 map_flags) 332 void *key, void *value, u64 map_flags)
333{ 333{
334 struct bpf_array *array = container_of(map, struct bpf_array, map); 334 struct bpf_array *array = container_of(map, struct bpf_array, map);
335 void *new_ptr, *old_ptr; 335 void *new_ptr, *old_ptr;
@@ -342,7 +342,7 @@ static int fd_array_map_update_elem(struct bpf_map *map, void *key,
342 return -E2BIG; 342 return -E2BIG;
343 343
344 ufd = *(u32 *)value; 344 ufd = *(u32 *)value;
345 new_ptr = map->ops->map_fd_get_ptr(map, ufd); 345 new_ptr = map->ops->map_fd_get_ptr(map, map_file, ufd);
346 if (IS_ERR(new_ptr)) 346 if (IS_ERR(new_ptr))
347 return PTR_ERR(new_ptr); 347 return PTR_ERR(new_ptr);
348 348
@@ -371,10 +371,12 @@ static int fd_array_map_delete_elem(struct bpf_map *map, void *key)
371 } 371 }
372} 372}
373 373
374static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd) 374static void *prog_fd_array_get_ptr(struct bpf_map *map,
375 struct file *map_file, int fd)
375{ 376{
376 struct bpf_array *array = container_of(map, struct bpf_array, map); 377 struct bpf_array *array = container_of(map, struct bpf_array, map);
377 struct bpf_prog *prog = bpf_prog_get(fd); 378 struct bpf_prog *prog = bpf_prog_get(fd);
379
378 if (IS_ERR(prog)) 380 if (IS_ERR(prog))
379 return prog; 381 return prog;
380 382
@@ -382,14 +384,13 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd)
382 bpf_prog_put(prog); 384 bpf_prog_put(prog);
383 return ERR_PTR(-EINVAL); 385 return ERR_PTR(-EINVAL);
384 } 386 }
387
385 return prog; 388 return prog;
386} 389}
387 390
388static void prog_fd_array_put_ptr(void *ptr) 391static void prog_fd_array_put_ptr(void *ptr)
389{ 392{
390 struct bpf_prog *prog = ptr; 393 bpf_prog_put(ptr);
391
392 bpf_prog_put_rcu(prog);
393} 394}
394 395
395/* decrement refcnt of all bpf_progs that are stored in this map */ 396/* decrement refcnt of all bpf_progs that are stored in this map */
@@ -407,7 +408,6 @@ static const struct bpf_map_ops prog_array_ops = {
407 .map_free = fd_array_map_free, 408 .map_free = fd_array_map_free,
408 .map_get_next_key = array_map_get_next_key, 409 .map_get_next_key = array_map_get_next_key,
409 .map_lookup_elem = fd_array_map_lookup_elem, 410 .map_lookup_elem = fd_array_map_lookup_elem,
410 .map_update_elem = fd_array_map_update_elem,
411 .map_delete_elem = fd_array_map_delete_elem, 411 .map_delete_elem = fd_array_map_delete_elem,
412 .map_fd_get_ptr = prog_fd_array_get_ptr, 412 .map_fd_get_ptr = prog_fd_array_get_ptr,
413 .map_fd_put_ptr = prog_fd_array_put_ptr, 413 .map_fd_put_ptr = prog_fd_array_put_ptr,
@@ -425,59 +425,105 @@ static int __init register_prog_array_map(void)
425} 425}
426late_initcall(register_prog_array_map); 426late_initcall(register_prog_array_map);
427 427
428static void perf_event_array_map_free(struct bpf_map *map) 428static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,
429 struct file *map_file)
429{ 430{
430 bpf_fd_array_map_clear(map); 431 struct bpf_event_entry *ee;
431 fd_array_map_free(map); 432
433 ee = kzalloc(sizeof(*ee), GFP_ATOMIC);
434 if (ee) {
435 ee->event = perf_file->private_data;
436 ee->perf_file = perf_file;
437 ee->map_file = map_file;
438 }
439
440 return ee;
432} 441}
433 442
434static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd) 443static void __bpf_event_entry_free(struct rcu_head *rcu)
435{ 444{
436 struct perf_event *event; 445 struct bpf_event_entry *ee;
437 const struct perf_event_attr *attr;
438 struct file *file;
439 446
440 file = perf_event_get(fd); 447 ee = container_of(rcu, struct bpf_event_entry, rcu);
441 if (IS_ERR(file)) 448 fput(ee->perf_file);
442 return file; 449 kfree(ee);
450}
443 451
444 event = file->private_data; 452static void bpf_event_entry_free_rcu(struct bpf_event_entry *ee)
453{
454 call_rcu(&ee->rcu, __bpf_event_entry_free);
455}
445 456
446 attr = perf_event_attrs(event); 457static void *perf_event_fd_array_get_ptr(struct bpf_map *map,
447 if (IS_ERR(attr)) 458 struct file *map_file, int fd)
448 goto err; 459{
460 const struct perf_event_attr *attr;
461 struct bpf_event_entry *ee;
462 struct perf_event *event;
463 struct file *perf_file;
449 464
450 if (attr->inherit) 465 perf_file = perf_event_get(fd);
451 goto err; 466 if (IS_ERR(perf_file))
467 return perf_file;
452 468
453 if (attr->type == PERF_TYPE_RAW) 469 event = perf_file->private_data;
454 return file; 470 ee = ERR_PTR(-EINVAL);
455 471
456 if (attr->type == PERF_TYPE_HARDWARE) 472 attr = perf_event_attrs(event);
457 return file; 473 if (IS_ERR(attr) || attr->inherit)
474 goto err_out;
475
476 switch (attr->type) {
477 case PERF_TYPE_SOFTWARE:
478 if (attr->config != PERF_COUNT_SW_BPF_OUTPUT)
479 goto err_out;
480 /* fall-through */
481 case PERF_TYPE_RAW:
482 case PERF_TYPE_HARDWARE:
483 ee = bpf_event_entry_gen(perf_file, map_file);
484 if (ee)
485 return ee;
486 ee = ERR_PTR(-ENOMEM);
487 /* fall-through */
488 default:
489 break;
490 }
458 491
459 if (attr->type == PERF_TYPE_SOFTWARE && 492err_out:
460 attr->config == PERF_COUNT_SW_BPF_OUTPUT) 493 fput(perf_file);
461 return file; 494 return ee;
462err:
463 fput(file);
464 return ERR_PTR(-EINVAL);
465} 495}
466 496
467static void perf_event_fd_array_put_ptr(void *ptr) 497static void perf_event_fd_array_put_ptr(void *ptr)
468{ 498{
469 fput((struct file *)ptr); 499 bpf_event_entry_free_rcu(ptr);
500}
501
502static void perf_event_fd_array_release(struct bpf_map *map,
503 struct file *map_file)
504{
505 struct bpf_array *array = container_of(map, struct bpf_array, map);
506 struct bpf_event_entry *ee;
507 int i;
508
509 rcu_read_lock();
510 for (i = 0; i < array->map.max_entries; i++) {
511 ee = READ_ONCE(array->ptrs[i]);
512 if (ee && ee->map_file == map_file)
513 fd_array_map_delete_elem(map, &i);
514 }
515 rcu_read_unlock();
470} 516}
471 517
472static const struct bpf_map_ops perf_event_array_ops = { 518static const struct bpf_map_ops perf_event_array_ops = {
473 .map_alloc = fd_array_map_alloc, 519 .map_alloc = fd_array_map_alloc,
474 .map_free = perf_event_array_map_free, 520 .map_free = fd_array_map_free,
475 .map_get_next_key = array_map_get_next_key, 521 .map_get_next_key = array_map_get_next_key,
476 .map_lookup_elem = fd_array_map_lookup_elem, 522 .map_lookup_elem = fd_array_map_lookup_elem,
477 .map_update_elem = fd_array_map_update_elem,
478 .map_delete_elem = fd_array_map_delete_elem, 523 .map_delete_elem = fd_array_map_delete_elem,
479 .map_fd_get_ptr = perf_event_fd_array_get_ptr, 524 .map_fd_get_ptr = perf_event_fd_array_get_ptr,
480 .map_fd_put_ptr = perf_event_fd_array_put_ptr, 525 .map_fd_put_ptr = perf_event_fd_array_put_ptr,
526 .map_release = perf_event_fd_array_release,
481}; 527};
482 528
483static struct bpf_map_type_list perf_event_array_type __read_mostly = { 529static struct bpf_map_type_list perf_event_array_type __read_mostly = {
@@ -491,3 +537,46 @@ static int __init register_perf_event_array_map(void)
491 return 0; 537 return 0;
492} 538}
493late_initcall(register_perf_event_array_map); 539late_initcall(register_perf_event_array_map);
540
541#ifdef CONFIG_SOCK_CGROUP_DATA
542static void *cgroup_fd_array_get_ptr(struct bpf_map *map,
543 struct file *map_file /* not used */,
544 int fd)
545{
546 return cgroup_get_from_fd(fd);
547}
548
549static void cgroup_fd_array_put_ptr(void *ptr)
550{
551 /* cgroup_put free cgrp after a rcu grace period */
552 cgroup_put(ptr);
553}
554
555static void cgroup_fd_array_free(struct bpf_map *map)
556{
557 bpf_fd_array_map_clear(map);
558 fd_array_map_free(map);
559}
560
561static const struct bpf_map_ops cgroup_array_ops = {
562 .map_alloc = fd_array_map_alloc,
563 .map_free = cgroup_fd_array_free,
564 .map_get_next_key = array_map_get_next_key,
565 .map_lookup_elem = fd_array_map_lookup_elem,
566 .map_delete_elem = fd_array_map_delete_elem,
567 .map_fd_get_ptr = cgroup_fd_array_get_ptr,
568 .map_fd_put_ptr = cgroup_fd_array_put_ptr,
569};
570
571static struct bpf_map_type_list cgroup_array_type __read_mostly = {
572 .ops = &cgroup_array_ops,
573 .type = BPF_MAP_TYPE_CGROUP_ARRAY,
574};
575
576static int __init register_cgroup_array_map(void)
577{
578 bpf_register_map_type(&cgroup_array_type);
579 return 0;
580}
581late_initcall(register_cgroup_array_map);
582#endif
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index b94a36550591..03fd23d4d587 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -719,14 +719,13 @@ select_insn:
719 719
720 if (unlikely(index >= array->map.max_entries)) 720 if (unlikely(index >= array->map.max_entries))
721 goto out; 721 goto out;
722
723 if (unlikely(tail_call_cnt > MAX_TAIL_CALL_CNT)) 722 if (unlikely(tail_call_cnt > MAX_TAIL_CALL_CNT))
724 goto out; 723 goto out;
725 724
726 tail_call_cnt++; 725 tail_call_cnt++;
727 726
728 prog = READ_ONCE(array->ptrs[index]); 727 prog = READ_ONCE(array->ptrs[index]);
729 if (unlikely(!prog)) 728 if (!prog)
730 goto out; 729 goto out;
731 730
732 /* ARG1 at this point is guaranteed to point to CTX from 731 /* ARG1 at this point is guaranteed to point to CTX from
@@ -1055,9 +1054,11 @@ const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
1055 return NULL; 1054 return NULL;
1056} 1055}
1057 1056
1058const struct bpf_func_proto * __weak bpf_get_event_output_proto(void) 1057u64 __weak
1058bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
1059 void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
1059{ 1060{
1060 return NULL; 1061 return -ENOTSUPP;
1061} 1062}
1062 1063
1063/* Always built-in helper functions. */ 1064/* Always built-in helper functions. */
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index ad7a0573f71b..1ea3afba1a4f 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -101,7 +101,7 @@ const struct bpf_func_proto bpf_get_prandom_u32_proto = {
101 101
102static u64 bpf_get_smp_processor_id(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) 102static u64 bpf_get_smp_processor_id(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
103{ 103{
104 return raw_smp_processor_id(); 104 return smp_processor_id();
105} 105}
106 106
107const struct bpf_func_proto bpf_get_smp_processor_id_proto = { 107const struct bpf_func_proto bpf_get_smp_processor_id_proto = {
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index 318858edb1cd..5967b870a895 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -11,7 +11,7 @@
11 * version 2 as published by the Free Software Foundation. 11 * version 2 as published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/init.h>
15#include <linux/magic.h> 15#include <linux/magic.h>
16#include <linux/major.h> 16#include <linux/major.h>
17#include <linux/mount.h> 17#include <linux/mount.h>
@@ -367,8 +367,6 @@ static struct file_system_type bpf_fs_type = {
367 .kill_sb = kill_litter_super, 367 .kill_sb = kill_litter_super,
368}; 368};
369 369
370MODULE_ALIAS_FS("bpf");
371
372static int __init bpf_init(void) 370static int __init bpf_init(void)
373{ 371{
374 int ret; 372 int ret;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 46ecce4b79ed..228f962447a5 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -124,7 +124,12 @@ void bpf_map_put_with_uref(struct bpf_map *map)
124 124
125static int bpf_map_release(struct inode *inode, struct file *filp) 125static int bpf_map_release(struct inode *inode, struct file *filp)
126{ 126{
127 bpf_map_put_with_uref(filp->private_data); 127 struct bpf_map *map = filp->private_data;
128
129 if (map->ops->map_release)
130 map->ops->map_release(map, filp);
131
132 bpf_map_put_with_uref(map);
128 return 0; 133 return 0;
129} 134}
130 135
@@ -387,6 +392,13 @@ static int map_update_elem(union bpf_attr *attr)
387 err = bpf_percpu_hash_update(map, key, value, attr->flags); 392 err = bpf_percpu_hash_update(map, key, value, attr->flags);
388 } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { 393 } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
389 err = bpf_percpu_array_update(map, key, value, attr->flags); 394 err = bpf_percpu_array_update(map, key, value, attr->flags);
395 } else if (map->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
396 map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
397 map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY) {
398 rcu_read_lock();
399 err = bpf_fd_array_map_update_elem(map, f.file, key, value,
400 attr->flags);
401 rcu_read_unlock();
390 } else { 402 } else {
391 rcu_read_lock(); 403 rcu_read_lock();
392 err = map->ops->map_update_elem(map, key, value, attr->flags); 404 err = map->ops->map_update_elem(map, key, value, attr->flags);
@@ -612,7 +624,7 @@ static void bpf_prog_uncharge_memlock(struct bpf_prog *prog)
612 free_uid(user); 624 free_uid(user);
613} 625}
614 626
615static void __prog_put_common(struct rcu_head *rcu) 627static void __bpf_prog_put_rcu(struct rcu_head *rcu)
616{ 628{
617 struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu); 629 struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);
618 630
@@ -621,17 +633,10 @@ static void __prog_put_common(struct rcu_head *rcu)
621 bpf_prog_free(aux->prog); 633 bpf_prog_free(aux->prog);
622} 634}
623 635
624/* version of bpf_prog_put() that is called after a grace period */
625void bpf_prog_put_rcu(struct bpf_prog *prog)
626{
627 if (atomic_dec_and_test(&prog->aux->refcnt))
628 call_rcu(&prog->aux->rcu, __prog_put_common);
629}
630
631void bpf_prog_put(struct bpf_prog *prog) 636void bpf_prog_put(struct bpf_prog *prog)
632{ 637{
633 if (atomic_dec_and_test(&prog->aux->refcnt)) 638 if (atomic_dec_and_test(&prog->aux->refcnt))
634 __prog_put_common(&prog->aux->rcu); 639 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
635} 640}
636EXPORT_SYMBOL_GPL(bpf_prog_put); 641EXPORT_SYMBOL_GPL(bpf_prog_put);
637 642
@@ -639,7 +644,7 @@ static int bpf_prog_release(struct inode *inode, struct file *filp)
639{ 644{
640 struct bpf_prog *prog = filp->private_data; 645 struct bpf_prog *prog = filp->private_data;
641 646
642 bpf_prog_put_rcu(prog); 647 bpf_prog_put(prog);
643 return 0; 648 return 0;
644} 649}
645 650
@@ -653,7 +658,7 @@ int bpf_prog_new_fd(struct bpf_prog *prog)
653 O_RDWR | O_CLOEXEC); 658 O_RDWR | O_CLOEXEC);
654} 659}
655 660
656static struct bpf_prog *__bpf_prog_get(struct fd f) 661static struct bpf_prog *____bpf_prog_get(struct fd f)
657{ 662{
658 if (!f.file) 663 if (!f.file)
659 return ERR_PTR(-EBADF); 664 return ERR_PTR(-EBADF);
@@ -665,33 +670,50 @@ static struct bpf_prog *__bpf_prog_get(struct fd f)
665 return f.file->private_data; 670 return f.file->private_data;
666} 671}
667 672
668struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) 673struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
669{ 674{
670 if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) { 675 if (atomic_add_return(i, &prog->aux->refcnt) > BPF_MAX_REFCNT) {
671 atomic_dec(&prog->aux->refcnt); 676 atomic_sub(i, &prog->aux->refcnt);
672 return ERR_PTR(-EBUSY); 677 return ERR_PTR(-EBUSY);
673 } 678 }
674 return prog; 679 return prog;
675} 680}
681EXPORT_SYMBOL_GPL(bpf_prog_add);
676 682
677/* called by sockets/tracing/seccomp before attaching program to an event 683struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
678 * pairs with bpf_prog_put() 684{
679 */ 685 return bpf_prog_add(prog, 1);
680struct bpf_prog *bpf_prog_get(u32 ufd) 686}
687
688static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type)
681{ 689{
682 struct fd f = fdget(ufd); 690 struct fd f = fdget(ufd);
683 struct bpf_prog *prog; 691 struct bpf_prog *prog;
684 692
685 prog = __bpf_prog_get(f); 693 prog = ____bpf_prog_get(f);
686 if (IS_ERR(prog)) 694 if (IS_ERR(prog))
687 return prog; 695 return prog;
696 if (type && prog->type != *type) {
697 prog = ERR_PTR(-EINVAL);
698 goto out;
699 }
688 700
689 prog = bpf_prog_inc(prog); 701 prog = bpf_prog_inc(prog);
702out:
690 fdput(f); 703 fdput(f);
691
692 return prog; 704 return prog;
693} 705}
694EXPORT_SYMBOL_GPL(bpf_prog_get); 706
707struct bpf_prog *bpf_prog_get(u32 ufd)
708{
709 return __bpf_prog_get(ufd, NULL);
710}
711
712struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
713{
714 return __bpf_prog_get(ufd, &type);
715}
716EXPORT_SYMBOL_GPL(bpf_prog_get_type);
695 717
696/* last field in 'union bpf_attr' used by this command */ 718/* last field in 'union bpf_attr' used by this command */
697#define BPF_PROG_LOAD_LAST_FIELD kern_version 719#define BPF_PROG_LOAD_LAST_FIELD kern_version
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index eec9f90ba030..f72f23b8fdab 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -653,6 +653,16 @@ static int check_map_access(struct verifier_env *env, u32 regno, int off,
653 653
654#define MAX_PACKET_OFF 0xffff 654#define MAX_PACKET_OFF 0xffff
655 655
656static bool may_write_pkt_data(enum bpf_prog_type type)
657{
658 switch (type) {
659 case BPF_PROG_TYPE_XDP:
660 return true;
661 default:
662 return false;
663 }
664}
665
656static int check_packet_access(struct verifier_env *env, u32 regno, int off, 666static int check_packet_access(struct verifier_env *env, u32 regno, int off,
657 int size) 667 int size)
658{ 668{
@@ -713,6 +723,7 @@ static int check_ptr_alignment(struct verifier_env *env, struct reg_state *reg,
713 switch (env->prog->type) { 723 switch (env->prog->type) {
714 case BPF_PROG_TYPE_SCHED_CLS: 724 case BPF_PROG_TYPE_SCHED_CLS:
715 case BPF_PROG_TYPE_SCHED_ACT: 725 case BPF_PROG_TYPE_SCHED_ACT:
726 case BPF_PROG_TYPE_XDP:
716 break; 727 break;
717 default: 728 default:
718 verbose("verifier is misconfigured\n"); 729 verbose("verifier is misconfigured\n");
@@ -805,10 +816,15 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
805 err = check_stack_read(state, off, size, value_regno); 816 err = check_stack_read(state, off, size, value_regno);
806 } 817 }
807 } else if (state->regs[regno].type == PTR_TO_PACKET) { 818 } else if (state->regs[regno].type == PTR_TO_PACKET) {
808 if (t == BPF_WRITE) { 819 if (t == BPF_WRITE && !may_write_pkt_data(env->prog->type)) {
809 verbose("cannot write into packet\n"); 820 verbose("cannot write into packet\n");
810 return -EACCES; 821 return -EACCES;
811 } 822 }
823 if (t == BPF_WRITE && value_regno >= 0 &&
824 is_pointer_value(env, value_regno)) {
825 verbose("R%d leaks addr into packet\n", value_regno);
826 return -EACCES;
827 }
812 err = check_packet_access(env, regno, off, size); 828 err = check_packet_access(env, regno, off, size);
813 if (!err && t == BPF_READ && value_regno >= 0) 829 if (!err && t == BPF_READ && value_regno >= 0)
814 mark_reg_unknown_value(state->regs, value_regno); 830 mark_reg_unknown_value(state->regs, value_regno);
@@ -1035,6 +1051,10 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
1035 if (func_id != BPF_FUNC_get_stackid) 1051 if (func_id != BPF_FUNC_get_stackid)
1036 goto error; 1052 goto error;
1037 break; 1053 break;
1054 case BPF_MAP_TYPE_CGROUP_ARRAY:
1055 if (func_id != BPF_FUNC_skb_in_cgroup)
1056 goto error;
1057 break;
1038 default: 1058 default:
1039 break; 1059 break;
1040 } 1060 }
@@ -1054,6 +1074,10 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
1054 if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) 1074 if (map->map_type != BPF_MAP_TYPE_STACK_TRACE)
1055 goto error; 1075 goto error;
1056 break; 1076 break;
1077 case BPF_FUNC_skb_in_cgroup:
1078 if (map->map_type != BPF_MAP_TYPE_CGROUP_ARRAY)
1079 goto error;
1080 break;
1057 default: 1081 default:
1058 break; 1082 break;
1059 } 1083 }