From af1973281e8bd2ffd85e0f35fec229f756e4ea77 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 17 Apr 2017 22:02:09 +0000 Subject: [PATCH] Use kmem_malloc() instead of malloc(9) for the native amd64 filter. r316767 broke the BPF JIT compiler for amd64 because malloc()'d space is no longer executable. Discussed with: kib, alc --- sys/amd64/amd64/bpf_jit_machdep.c | 25 ++++++++++++++++++++++--- sys/i386/i386/bpf_jit_machdep.c | 16 ++++++++++++++-- sys/net/bpf_jitter.c | 8 +++----- sys/net/bpf_jitter.h | 1 + 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/sys/amd64/amd64/bpf_jit_machdep.c b/sys/amd64/amd64/bpf_jit_machdep.c index e8232813b8f0..f79917a52cfa 100644 --- a/sys/amd64/amd64/bpf_jit_machdep.c +++ b/sys/amd64/amd64/bpf_jit_machdep.c @@ -1,6 +1,6 @@ /*- * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2016 Jung-uk Kim + * Copyright (C) 2005-2017 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,10 +37,14 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include + #include +#include +#include +#include #else #include #include @@ -599,7 +603,11 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) *size = stream.cur_ip; #ifdef _KERNEL - stream.ibuf = malloc(*size, M_BPFJIT, M_NOWAIT); + /* + * We cannot use malloc(9) because DMAP is mapped as NX. + */ + stream.ibuf = (void *)kmem_malloc(kernel_arena, *size, + M_NOWAIT); if (stream.ibuf == NULL) break; #else @@ -648,3 +656,14 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) return ((bpf_filter_func)(void *)stream.ibuf); } + +void +bpf_jit_free(void *func, size_t size) +{ + +#ifdef _KERNEL + kmem_free(kernel_arena, (vm_offset_t)func, size); +#else + munmap(func, size); +#endif +} diff --git a/sys/i386/i386/bpf_jit_machdep.c b/sys/i386/i386/bpf_jit_machdep.c index 67a13cc6c2de..3620b316379e 100644 --- a/sys/i386/i386/bpf_jit_machdep.c +++ b/sys/i386/i386/bpf_jit_machdep.c @@ -1,6 +1,6 @@ /*- * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2016 Jung-uk Kim + * Copyright (C) 2005-2017 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,9 +37,10 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include + #include #else #include @@ -678,3 +679,14 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) return ((bpf_filter_func)(void *)stream.ibuf); } + +void +bpf_jit_free(void *func, size_t size) +{ + +#ifdef _KERNEL + free(func, M_BPFJIT); +#else + munmap(func, size); +#endif +} diff --git a/sys/net/bpf_jitter.c b/sys/net/bpf_jitter.c index 5c3b8e881d3b..a502f2feb157 100644 --- a/sys/net/bpf_jitter.c +++ b/sys/net/bpf_jitter.c @@ -1,6 +1,6 @@ /*- * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim + * Copyright (C) 2005-2017 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,13 +99,11 @@ void bpf_destroy_jit_filter(bpf_jit_filter *filter) { -#ifdef _KERNEL if (filter->func != bpf_jit_accept_all) - free(filter->func, M_BPFJIT); + bpf_jit_free(filter->func, filter->size); +#ifdef _KERNEL free(filter, M_BPFJIT); #else - if (filter->func != bpf_jit_accept_all) - munmap(filter->func, filter->size); free(filter); #endif } diff --git a/sys/net/bpf_jitter.h b/sys/net/bpf_jitter.h index 88a349df97e2..479205ea5ebd 100644 --- a/sys/net/bpf_jitter.h +++ b/sys/net/bpf_jitter.h @@ -86,5 +86,6 @@ void bpf_destroy_jit_filter(bpf_jit_filter *filter); struct bpf_insn; bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); +void bpf_jit_free(void *, size_t); #endif /* _NET_BPF_JITTER_H_ */