aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-28 23:17:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-28 23:17:49 -0400
commit9f51ae62c84a23ade0ba86457d30a30c9db0c50f (patch)
treed71bf5c81f17629d3d1b3131e0842c02bd9a7dd6 /kernel/bpf/core.c
parent53b3b6bbfde6aae8d1ededc86ad4e0e1e00eb5f8 (diff)
parent747569b0a7c537d680bc94a988be6caad9960488 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) GRO overflow entries are not unlinked properly, resulting in list poison pointers being dereferenced. 2) Fix bridge build with ipv6 disabled, from Nikolay Aleksandrov. 3) Direct packet access and other fixes in BPF from Daniel Borkmann. 4) gred_change_table_def() gets passed the wrong pointer, a pointer to a set of unparsed attributes instead of the attribute itself. From Jakub Kicinski. 5) Allow macsec device to be brought up even if it's lowerdev is down, from Sabrina Dubroca. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: net: diag: document swapped src/dst in udp_dump_one. macsec: let the administrator set UP state even if lowerdev is down macsec: update operstate when lower device changes net: sched: gred: pass the right attribute to gred_change_table_def() ptp: drop redundant kasprintf() to create worker name net: bridge: remove ipv6 zero address check in mcast queries net: Properly unlink GRO packets on overflow. bpf: fix wrong helper enablement in cgroup local storage bpf: add bpf_jit_limit knob to restrict unpriv allocations bpf: make direct packet write unclone more robust bpf: fix leaking uninitialized memory on pop/peek helpers bpf: fix direct packet write into pop/peek helpers bpf: fix cg_skb types to hint access type in may_access_direct_pkt_data bpf: fix direct packet access for flow dissector progs bpf: disallow direct packet access for unpriv in cg_skb bpf: fix test suite to enable all unpriv program types bpf, btf: fix a missing check bug in btf_parse selftests/bpf: add config fragments BPF_STREAM_PARSER and XDP_SOCKETS bpf: devmap: fix wrong interface selection in notifier_call
Diffstat (limited to 'kernel/bpf/core.c')
-rw-r--r--kernel/bpf/core.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 7c7eeea8cffc..6377225b2082 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -365,10 +365,13 @@ void bpf_prog_kallsyms_del_all(struct bpf_prog *fp)
365} 365}
366 366
367#ifdef CONFIG_BPF_JIT 367#ifdef CONFIG_BPF_JIT
368# define BPF_JIT_LIMIT_DEFAULT (PAGE_SIZE * 40000)
369
368/* All BPF JIT sysctl knobs here. */ 370/* All BPF JIT sysctl knobs here. */
369int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON); 371int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
370int bpf_jit_harden __read_mostly; 372int bpf_jit_harden __read_mostly;
371int bpf_jit_kallsyms __read_mostly; 373int bpf_jit_kallsyms __read_mostly;
374int bpf_jit_limit __read_mostly = BPF_JIT_LIMIT_DEFAULT;
372 375
373static __always_inline void 376static __always_inline void
374bpf_get_prog_addr_region(const struct bpf_prog *prog, 377bpf_get_prog_addr_region(const struct bpf_prog *prog,
@@ -577,27 +580,64 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
577 return ret; 580 return ret;
578} 581}
579 582
583static atomic_long_t bpf_jit_current;
584
585#if defined(MODULES_VADDR)
586static int __init bpf_jit_charge_init(void)
587{
588 /* Only used as heuristic here to derive limit. */
589 bpf_jit_limit = min_t(u64, round_up((MODULES_END - MODULES_VADDR) >> 2,
590 PAGE_SIZE), INT_MAX);
591 return 0;
592}
593pure_initcall(bpf_jit_charge_init);
594#endif
595
596static int bpf_jit_charge_modmem(u32 pages)
597{
598 if (atomic_long_add_return(pages, &bpf_jit_current) >
599 (bpf_jit_limit >> PAGE_SHIFT)) {
600 if (!capable(CAP_SYS_ADMIN)) {
601 atomic_long_sub(pages, &bpf_jit_current);
602 return -EPERM;
603 }
604 }
605
606 return 0;
607}
608
609static void bpf_jit_uncharge_modmem(u32 pages)
610{
611 atomic_long_sub(pages, &bpf_jit_current);
612}
613
580struct bpf_binary_header * 614struct bpf_binary_header *
581bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, 615bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
582 unsigned int alignment, 616 unsigned int alignment,
583 bpf_jit_fill_hole_t bpf_fill_ill_insns) 617 bpf_jit_fill_hole_t bpf_fill_ill_insns)
584{ 618{
585 struct bpf_binary_header *hdr; 619 struct bpf_binary_header *hdr;
586 unsigned int size, hole, start; 620 u32 size, hole, start, pages;
587 621
588 /* Most of BPF filters are really small, but if some of them 622 /* Most of BPF filters are really small, but if some of them
589 * fill a page, allow at least 128 extra bytes to insert a 623 * fill a page, allow at least 128 extra bytes to insert a
590 * random section of illegal instructions. 624 * random section of illegal instructions.
591 */ 625 */
592 size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE); 626 size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE);
627 pages = size / PAGE_SIZE;
628
629 if (bpf_jit_charge_modmem(pages))
630 return NULL;
593 hdr = module_alloc(size); 631 hdr = module_alloc(size);
594 if (hdr == NULL) 632 if (!hdr) {
633 bpf_jit_uncharge_modmem(pages);
595 return NULL; 634 return NULL;
635 }
596 636
597 /* Fill space with illegal/arch-dep instructions. */ 637 /* Fill space with illegal/arch-dep instructions. */
598 bpf_fill_ill_insns(hdr, size); 638 bpf_fill_ill_insns(hdr, size);
599 639
600 hdr->pages = size / PAGE_SIZE; 640 hdr->pages = pages;
601 hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)), 641 hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)),
602 PAGE_SIZE - sizeof(*hdr)); 642 PAGE_SIZE - sizeof(*hdr));
603 start = (get_random_int() % hole) & ~(alignment - 1); 643 start = (get_random_int() % hole) & ~(alignment - 1);
@@ -610,7 +650,10 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
610 650
611void bpf_jit_binary_free(struct bpf_binary_header *hdr) 651void bpf_jit_binary_free(struct bpf_binary_header *hdr)
612{ 652{
653 u32 pages = hdr->pages;
654
613 module_memfree(hdr); 655 module_memfree(hdr);
656 bpf_jit_uncharge_modmem(pages);
614} 657}
615 658
616/* This symbol is only overridden by archs that have different 659/* This symbol is only overridden by archs that have different