aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/core.c
diff options
context:
space:
mode:
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