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
This commit is contained in:
Jung-uk Kim 2017-04-17 22:02:09 +00:00
parent c7ff2b13d1
commit af1973281e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=317072
4 changed files with 40 additions and 10 deletions

View File

@ -1,6 +1,6 @@
/*-
* Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
* Copyright (C) 2005-2016 Jung-uk Kim <jkim@FreeBSD.org>
* Copyright (C) 2005-2017 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -37,10 +37,14 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
#else
#include <stdlib.h>
#include <string.h>
@ -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
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
* Copyright (C) 2005-2016 Jung-uk Kim <jkim@FreeBSD.org>
* Copyright (C) 2005-2017 Jung-uk Kim <jkim@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -37,9 +37,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#else
#include <stdlib.h>
@ -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
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
* Copyright (C) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org>
* Copyright (C) 2005-2017 Jung-uk Kim <jkim@FreeBSD.org>
* 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
}

View File

@ -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_ */