summaryrefslogtreecommitdiff
path: root/kernel/bpf/core.c
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2019-09-04 14:08:16 -0700
committerMichael Bestas <mkbestas@lineageos.org>2022-04-19 00:51:53 +0300
commit1f459d731993dcaa501ec8fd6b03ff43f42bf108 (patch)
treefbcc3315bcbd81cf9b5b2cf3e3d6882d84b8fa89 /kernel/bpf/core.c
parentc6da67a69b16e2f7ad9127b5f047d10b3c8a20b3 (diff)
ANDROID: bpf: validate bpf_func when BPF_JIT is enabled with CFI
With CONFIG_BPF_JIT, the kernel makes indirect calls to dynamically generated code, which the compile-time Control-Flow Integrity (CFI) checking cannot validate. This change adds basic sanity checking to ensure we are jumping to a valid location, which narrows down the attack surface on the stored pointer. In addition, this change adds a weak arch_bpf_jit_check_func function, which architectures that implement BPF JIT can override to perform additional validation, such as verifying that the pointer points to the correct memory region. Bug: 140377409 Change-Id: I8ebac6637ab6bd9db44716b1c742add267298669 Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Diffstat (limited to 'kernel/bpf/core.c')
-rw-r--r--kernel/bpf/core.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 6e407cd56cc4..95ffe1fac0bf 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -257,6 +257,14 @@ static void bpf_jit_uncharge_modmem(u32 pages)
atomic_long_sub(pages, &bpf_jit_current);
}
+#if IS_ENABLED(CONFIG_BPF_JIT) && IS_ENABLED(CONFIG_CFI_CLANG)
+bool __weak arch_bpf_jit_check_func(const struct bpf_prog *prog)
+{
+ return true;
+}
+EXPORT_SYMBOL(arch_bpf_jit_check_func);
+#endif
+
struct bpf_binary_header *
bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
unsigned int alignment,
@@ -283,6 +291,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
/* Fill space with illegal/arch-dep instructions. */
bpf_fill_ill_insns(hdr, size);
+ bpf_jit_set_header_magic(hdr);
hdr->pages = pages;
hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)),
PAGE_SIZE - sizeof(*hdr));