[PATCH bpf-next 4/5] bpf, x86: make sure allocation in arch_bpf_trampoline_size() is writable
From: Mike Rapoport (Microsoft)
Date: Fri Jun 26 2026 - 14:43:25 EST
arch_bpf_trampoline_size() allocates a buffer to get actual size required
for a trampoline.
This buffer must be in the module address space because
__arch_prepare_bpf_trampoline() calculates rel32 offsets relatively to
that buffer.
In preparation for enabling ROX mode for EXECMEM_BPF make sure that the
allocated memory is writable.
Add bpf_jit_alloc_exec_rw() wrapper for execmem_alloc_rw() and use it for
buffer allocation in arch_bpf_trampoline_size().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
---
arch/x86/net/bpf_jit_comp.c | 5 ++---
include/linux/filter.h | 1 +
kernel/bpf/core.c | 5 +++++
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 054e043ffcd2..ba562d3bf031 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -3703,13 +3703,12 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
int ret;
/* Allocate a temporary buffer for __arch_prepare_bpf_trampoline().
- * This will NOT cause fragmentation in direct map, as we do not
- * call set_memory_*() on this buffer.
*
* We cannot use kvmalloc here, because we need image to be in
* module memory range.
+ * Since it must be writable use bpf_jit_alloc_exec_rw().
*/
- image = bpf_jit_alloc_exec(PAGE_SIZE);
+ image = bpf_jit_alloc_exec_rw(PAGE_SIZE);
if (!image)
return -ENOMEM;
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 67d337ede91b..773b16f06572 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1323,6 +1323,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
void bpf_jit_binary_free(struct bpf_binary_header *hdr);
u64 bpf_jit_alloc_exec_limit(void);
void *bpf_jit_alloc_exec(unsigned long size);
+void *bpf_jit_alloc_exec_rw(unsigned long size);
void bpf_jit_free_exec(void *addr);
void bpf_jit_free(struct bpf_prog *fp);
struct bpf_binary_header *
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 9666b6cca797..55284b5d0292 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1072,6 +1072,11 @@ void *bpf_jit_alloc_exec(unsigned long size)
return execmem_alloc(EXECMEM_BPF, size);
}
+void *bpf_jit_alloc_exec_rw(unsigned long size)
+{
+ return execmem_alloc_rw(EXECMEM_BPF, size);
+}
+
void bpf_jit_free_exec(void *addr)
{
execmem_free(addr);
--
2.53.0