Message ID | 20181123094152.21368-3-ard.biesheuvel@linaro.org |
---|---|
State | New |
Headers | show |
Series | bpf: permit JIT allocations to be served outside the module region | expand |
Hi Ard,
I love your patch! Perhaps something to improve:
[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on v4.20-rc4 next-20181123]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/bpf-permit-JIT-allocations-to-be-served-outside-the-module-region/20181126-024110
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
include/linux/slab.h:332:43: warning: dubious: x & !y
kernel/bpf/core.c:612:6: warning: symbol 'bpf_jit_alloc_exec' was not declared. Should it be static?
>> kernel/bpf/core.c:619:24: warning: incorrect type in argument 1 (different modifiers)
kernel/bpf/core.c:619:24: expected void *module_region
kernel/bpf/core.c:619:24: got void const *addr
kernel/bpf/core.c:617:13: warning: symbol 'bpf_jit_free_exec' was not declared. Should it be static?
include/linux/slab.h:332:43: warning: dubious: x & !y
kernel/bpf/core.c:1608:9: warning: incorrect type in argument 1 (different address spaces)
kernel/bpf/core.c:1608:9: expected struct callback_head *head
kernel/bpf/core.c:1608:9: got struct callback_head [noderef] <asn:4>*<noident>
include/linux/slab.h:332:43: warning: dubious: x & !y
kernel/bpf/core.c:1682:44: warning: incorrect type in initializer (different address spaces)
kernel/bpf/core.c:1682:44: expected struct bpf_prog_array_item *item
kernel/bpf/core.c:1682:44: got struct bpf_prog_array_item [noderef] <asn:4>*<noident>
kernel/bpf/core.c:1706:26: warning: incorrect type in assignment (different address spaces)
kernel/bpf/core.c:1706:26: expected struct bpf_prog_array_item *existing
kernel/bpf/core.c:1706:26: got struct bpf_prog_array_item [noderef] <asn:4>*<noident>
kernel/bpf/core.c:1740:26: warning: incorrect type in assignment (different address spaces)
kernel/bpf/core.c:1740:26: expected struct bpf_prog_array_item *[assigned] existing
kernel/bpf/core.c:1740:26: got struct bpf_prog_array_item [noderef] <asn:4>*<noident>
include/trace/events/xdp.h:28:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:53:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:111:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:126:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:161:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:196:1: warning: Using plain integer as NULL pointer
include/trace/events/xdp.h:231:1: warning: Using plain integer as NULL pointer
kernel/bpf/core.c:999:18: warning: Initializer entry defined twice
kernel/bpf/core.c:1001:17: also defined here
kernel/bpf/core.c: In function 'bpf_jit_free_exec':
kernel/bpf/core.c:619:17: warning: passing argument 1 of 'module_memfree' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
module_memfree(addr);
^~~~
In file included from kernel/bpf/core.c:28:0:
include/linux/moduleloader.h:30:6: note: expected 'void *' but argument is of type 'const void *'
void module_memfree(void *module_region);
^~~~~~~~~~~~~~
vim +619 kernel/bpf/core.c
ede95a63b Daniel Borkmann 2018-10-23 611
eff59cbcb Ard Biesheuvel 2018-11-23 @612 void *__weak bpf_jit_alloc_exec(unsigned long size)
eff59cbcb Ard Biesheuvel 2018-11-23 613 {
eff59cbcb Ard Biesheuvel 2018-11-23 614 return module_alloc(size);
eff59cbcb Ard Biesheuvel 2018-11-23 615 }
eff59cbcb Ard Biesheuvel 2018-11-23 616
eff59cbcb Ard Biesheuvel 2018-11-23 617 void __weak bpf_jit_free_exec(const void *addr)
eff59cbcb Ard Biesheuvel 2018-11-23 618 {
eff59cbcb Ard Biesheuvel 2018-11-23 @619 module_memfree(addr);
eff59cbcb Ard Biesheuvel 2018-11-23 620 }
eff59cbcb Ard Biesheuvel 2018-11-23 621
:::::: The code at line 619 was first introduced by commit
:::::: eff59cbcb348cb3df3fd41aba28df574c6cf7c27 bpf: add __weak hook for allocating executable memory
:::::: TO: Ard Biesheuvel <ard.biesheuvel@linaro.org>
:::::: CC: 0day robot <lkp@intel.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index b96442960aea..506e319da98f 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -69,6 +69,9 @@ #define PCI_IO_END (VMEMMAP_START - SZ_2M) #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) #define FIXADDR_TOP (PCI_IO_START - SZ_2M) +#define BPF_JIT_REGION_BASE (VMALLOC_END) +#define BPF_JIT_REGION_SIZE (SZ_128M) +#define BPF_JIT_REGION_END (BPF_JIT_REGION_BASE + BPF_JIT_REGION_SIZE) #define KERNEL_START _text #define KERNEL_END _end diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 50b1ef8584c0..9db98a4cd9b4 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -31,7 +31,7 @@ * and fixed mappings */ #define VMALLOC_START (MODULES_END) -#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - BPF_JIT_REGION_SIZE - SZ_64K) #define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index a6fdaea07c63..298beba29fa5 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -940,3 +940,16 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) tmp : orig_prog); return prog; } + +void *bpf_jit_alloc_exec(unsigned long size) +{ + return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_BASE, + BPF_JIT_REGION_END, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, + __builtin_return_address(0)); +} + +void bpf_jit_free_exec(const void *addr) +{ + return vfree(addr); +}
The arm64 module region is a 128 MB region that is kept close to the core kernel, in order to ensure that relative branches are always in range. So using the same region for programs that do not have this restriction is wasteful, and preferably avoided. Now that the core BPF JIT code permits the alloc/free routines to be overridden, implement them by vmalloc()/vfree() calls from a dedicated 128 MB region set aside for BPF programs. This ensures that BPF programs are still in branching range of each other, which is something the JIT currently depends upon (and is not guaranteed when using module_alloc() on KASLR kernels like we do currently). It also ensures that placement of BPF programs does not correlate with the placement of the core kernel or modules, making it less likely that leaking the former will reveal the latter. This also solves an issue under KASAN, where shadow memory is needlessly allocated for all BPF programs (which don't require KASAN shadow pages since they are not KASAN instrumented) Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/arm64/include/asm/memory.h | 3 +++ arch/arm64/include/asm/pgtable.h | 2 +- arch/arm64/net/bpf_jit_comp.c | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) -- 2.17.1