diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-09 19:59:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-09 19:59:03 -0400 |
commit | 60005c60b1ea807013bcbbfe9309fc924a3881f0 (patch) | |
tree | 50f1a085ddd7923b2b3c2764c850d0c02447d32a | |
parent | ca777eff51f7fbaebd954e645d8ecb781a906b4a (diff) | |
parent | 286aad3c4014ca825c447e07e24f8929e6d266d2 (diff) |
Merge branch 'bpf-next'
Daniel Borkmann says:
====================
BPF updates
[ Set applies on top of current net-next but also on top of
Alexei's latest patches. Please see individual patches for
more details. ]
Changelog:
v1->v2:
- Removed paragraph in 1st commit message
- Rest stays the same
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/arm/net/bpf_jit_32.c | 34 | ||||
-rw-r--r-- | arch/mips/net/bpf_jit.c | 2 | ||||
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp.c | 2 | ||||
-rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 47 | ||||
-rw-r--r-- | arch/sparc/net/bpf_jit_comp.c | 2 | ||||
-rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 52 | ||||
-rw-r--r-- | include/linux/filter.h | 19 | ||||
-rw-r--r-- | kernel/bpf/core.c | 39 | ||||
-rw-r--r-- | net/core/filter.c | 2 |
9 files changed, 108 insertions, 91 deletions
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index a76623bcf722..6b45f649eff0 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/filter.h> | 14 | #include <linux/filter.h> |
15 | #include <linux/moduleloader.h> | ||
16 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
17 | #include <linux/string.h> | 16 | #include <linux/string.h> |
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
@@ -174,6 +173,15 @@ static inline bool is_load_to_a(u16 inst) | |||
174 | } | 173 | } |
175 | } | 174 | } |
176 | 175 | ||
176 | static void jit_fill_hole(void *area, unsigned int size) | ||
177 | { | ||
178 | /* Insert illegal UND instructions. */ | ||
179 | u32 *ptr, fill_ins = 0xe7ffffff; | ||
180 | /* We are guaranteed to have aligned memory. */ | ||
181 | for (ptr = area; size >= sizeof(u32); size -= sizeof(u32)) | ||
182 | *ptr++ = fill_ins; | ||
183 | } | ||
184 | |||
177 | static void build_prologue(struct jit_ctx *ctx) | 185 | static void build_prologue(struct jit_ctx *ctx) |
178 | { | 186 | { |
179 | u16 reg_set = saved_regs(ctx); | 187 | u16 reg_set = saved_regs(ctx); |
@@ -859,9 +867,11 @@ b_epilogue: | |||
859 | 867 | ||
860 | void bpf_jit_compile(struct bpf_prog *fp) | 868 | void bpf_jit_compile(struct bpf_prog *fp) |
861 | { | 869 | { |
870 | struct bpf_binary_header *header; | ||
862 | struct jit_ctx ctx; | 871 | struct jit_ctx ctx; |
863 | unsigned tmp_idx; | 872 | unsigned tmp_idx; |
864 | unsigned alloc_size; | 873 | unsigned alloc_size; |
874 | u8 *target_ptr; | ||
865 | 875 | ||
866 | if (!bpf_jit_enable) | 876 | if (!bpf_jit_enable) |
867 | return; | 877 | return; |
@@ -897,13 +907,15 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
897 | /* there's nothing after the epilogue on ARMv7 */ | 907 | /* there's nothing after the epilogue on ARMv7 */ |
898 | build_epilogue(&ctx); | 908 | build_epilogue(&ctx); |
899 | #endif | 909 | #endif |
900 | |||
901 | alloc_size = 4 * ctx.idx; | 910 | alloc_size = 4 * ctx.idx; |
902 | ctx.target = module_alloc(alloc_size); | 911 | header = bpf_jit_binary_alloc(alloc_size, &target_ptr, |
903 | if (unlikely(ctx.target == NULL)) | 912 | 4, jit_fill_hole); |
913 | if (header == NULL) | ||
904 | goto out; | 914 | goto out; |
905 | 915 | ||
916 | ctx.target = (u32 *) target_ptr; | ||
906 | ctx.idx = 0; | 917 | ctx.idx = 0; |
918 | |||
907 | build_prologue(&ctx); | 919 | build_prologue(&ctx); |
908 | build_body(&ctx); | 920 | build_body(&ctx); |
909 | build_epilogue(&ctx); | 921 | build_epilogue(&ctx); |
@@ -919,8 +931,9 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
919 | /* there are 2 passes here */ | 931 | /* there are 2 passes here */ |
920 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); | 932 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); |
921 | 933 | ||
934 | set_memory_ro((unsigned long)header, header->pages); | ||
922 | fp->bpf_func = (void *)ctx.target; | 935 | fp->bpf_func = (void *)ctx.target; |
923 | fp->jited = 1; | 936 | fp->jited = true; |
924 | out: | 937 | out: |
925 | kfree(ctx.offsets); | 938 | kfree(ctx.offsets); |
926 | return; | 939 | return; |
@@ -928,8 +941,15 @@ out: | |||
928 | 941 | ||
929 | void bpf_jit_free(struct bpf_prog *fp) | 942 | void bpf_jit_free(struct bpf_prog *fp) |
930 | { | 943 | { |
931 | if (fp->jited) | 944 | unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; |
932 | module_free(NULL, fp->bpf_func); | 945 | struct bpf_binary_header *header = (void *)addr; |
946 | |||
947 | if (!fp->jited) | ||
948 | goto free_filter; | ||
949 | |||
950 | set_memory_rw(addr, header->pages); | ||
951 | bpf_jit_binary_free(header); | ||
933 | 952 | ||
953 | free_filter: | ||
934 | bpf_prog_unlock_free(fp); | 954 | bpf_prog_unlock_free(fp); |
935 | } | 955 | } |
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index cfa83cf2447d..0e97ccd29fe3 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c | |||
@@ -1417,7 +1417,7 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
1417 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); | 1417 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); |
1418 | 1418 | ||
1419 | fp->bpf_func = (void *)ctx.target; | 1419 | fp->bpf_func = (void *)ctx.target; |
1420 | fp->jited = 1; | 1420 | fp->jited = true; |
1421 | 1421 | ||
1422 | out: | 1422 | out: |
1423 | kfree(ctx.offsets); | 1423 | kfree(ctx.offsets); |
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 40c53ff59124..cbae2dfd053c 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c | |||
@@ -686,7 +686,7 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
686 | ((u64 *)image)[0] = (u64)code_base; | 686 | ((u64 *)image)[0] = (u64)code_base; |
687 | ((u64 *)image)[1] = local_paca->kernel_toc; | 687 | ((u64 *)image)[1] = local_paca->kernel_toc; |
688 | fp->bpf_func = (void *)image; | 688 | fp->bpf_func = (void *)image; |
689 | fp->jited = 1; | 689 | fp->jited = true; |
690 | } | 690 | } |
691 | out: | 691 | out: |
692 | kfree(addrs); | 692 | kfree(addrs); |
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index f2833c5b218a..555f5c7e83ab 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -5,11 +5,9 @@ | |||
5 | * | 5 | * |
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | 6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
7 | */ | 7 | */ |
8 | #include <linux/moduleloader.h> | ||
9 | #include <linux/netdevice.h> | 8 | #include <linux/netdevice.h> |
10 | #include <linux/if_vlan.h> | 9 | #include <linux/if_vlan.h> |
11 | #include <linux/filter.h> | 10 | #include <linux/filter.h> |
12 | #include <linux/random.h> | ||
13 | #include <linux/init.h> | 11 | #include <linux/init.h> |
14 | #include <asm/cacheflush.h> | 12 | #include <asm/cacheflush.h> |
15 | #include <asm/facility.h> | 13 | #include <asm/facility.h> |
@@ -148,6 +146,12 @@ struct bpf_jit { | |||
148 | ret; \ | 146 | ret; \ |
149 | }) | 147 | }) |
150 | 148 | ||
149 | static void bpf_jit_fill_hole(void *area, unsigned int size) | ||
150 | { | ||
151 | /* Fill whole space with illegal instructions */ | ||
152 | memset(area, 0, size); | ||
153 | } | ||
154 | |||
151 | static void bpf_jit_prologue(struct bpf_jit *jit) | 155 | static void bpf_jit_prologue(struct bpf_jit *jit) |
152 | { | 156 | { |
153 | /* Save registers and create stack frame if necessary */ | 157 | /* Save registers and create stack frame if necessary */ |
@@ -780,38 +784,6 @@ out: | |||
780 | return -1; | 784 | return -1; |
781 | } | 785 | } |
782 | 786 | ||
783 | /* | ||
784 | * Note: for security reasons, bpf code will follow a randomly | ||
785 | * sized amount of illegal instructions. | ||
786 | */ | ||
787 | struct bpf_binary_header { | ||
788 | unsigned int pages; | ||
789 | u8 image[]; | ||
790 | }; | ||
791 | |||
792 | static struct bpf_binary_header *bpf_alloc_binary(unsigned int bpfsize, | ||
793 | u8 **image_ptr) | ||
794 | { | ||
795 | struct bpf_binary_header *header; | ||
796 | unsigned int sz, hole; | ||
797 | |||
798 | /* Most BPF filters are really small, but if some of them fill a page, | ||
799 | * allow at least 128 extra bytes for illegal instructions. | ||
800 | */ | ||
801 | sz = round_up(bpfsize + sizeof(*header) + 128, PAGE_SIZE); | ||
802 | header = module_alloc(sz); | ||
803 | if (!header) | ||
804 | return NULL; | ||
805 | memset(header, 0, sz); | ||
806 | header->pages = sz / PAGE_SIZE; | ||
807 | hole = min(sz - (bpfsize + sizeof(*header)), PAGE_SIZE - sizeof(*header)); | ||
808 | /* Insert random number of illegal instructions before BPF code | ||
809 | * and make sure the first instruction starts at an even address. | ||
810 | */ | ||
811 | *image_ptr = &header->image[(prandom_u32() % hole) & -2]; | ||
812 | return header; | ||
813 | } | ||
814 | |||
815 | void bpf_jit_compile(struct bpf_prog *fp) | 787 | void bpf_jit_compile(struct bpf_prog *fp) |
816 | { | 788 | { |
817 | struct bpf_binary_header *header = NULL; | 789 | struct bpf_binary_header *header = NULL; |
@@ -850,7 +822,8 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
850 | size = prg_len + lit_len; | 822 | size = prg_len + lit_len; |
851 | if (size >= BPF_SIZE_MAX) | 823 | if (size >= BPF_SIZE_MAX) |
852 | goto out; | 824 | goto out; |
853 | header = bpf_alloc_binary(size, &jit.start); | 825 | header = bpf_jit_binary_alloc(size, &jit.start, |
826 | 2, bpf_jit_fill_hole); | ||
854 | if (!header) | 827 | if (!header) |
855 | goto out; | 828 | goto out; |
856 | jit.prg = jit.mid = jit.start + prg_len; | 829 | jit.prg = jit.mid = jit.start + prg_len; |
@@ -869,7 +842,7 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
869 | if (jit.start) { | 842 | if (jit.start) { |
870 | set_memory_ro((unsigned long)header, header->pages); | 843 | set_memory_ro((unsigned long)header, header->pages); |
871 | fp->bpf_func = (void *) jit.start; | 844 | fp->bpf_func = (void *) jit.start; |
872 | fp->jited = 1; | 845 | fp->jited = true; |
873 | } | 846 | } |
874 | out: | 847 | out: |
875 | kfree(addrs); | 848 | kfree(addrs); |
@@ -884,7 +857,7 @@ void bpf_jit_free(struct bpf_prog *fp) | |||
884 | goto free_filter; | 857 | goto free_filter; |
885 | 858 | ||
886 | set_memory_rw(addr, header->pages); | 859 | set_memory_rw(addr, header->pages); |
887 | module_free(NULL, header); | 860 | bpf_jit_binary_free(header); |
888 | 861 | ||
889 | free_filter: | 862 | free_filter: |
890 | bpf_prog_unlock_free(fp); | 863 | bpf_prog_unlock_free(fp); |
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index f7a736b645e8..b2ad9dc5425e 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c | |||
@@ -801,7 +801,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; | |||
801 | if (image) { | 801 | if (image) { |
802 | bpf_flush_icache(image, image + proglen); | 802 | bpf_flush_icache(image, image + proglen); |
803 | fp->bpf_func = (void *)image; | 803 | fp->bpf_func = (void *)image; |
804 | fp->jited = 1; | 804 | fp->jited = true; |
805 | } | 805 | } |
806 | out: | 806 | out: |
807 | kfree(addrs); | 807 | kfree(addrs); |
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 06f8c17f5484..d56cd1f515bd 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
@@ -8,12 +8,10 @@ | |||
8 | * as published by the Free Software Foundation; version 2 | 8 | * as published by the Free Software Foundation; version 2 |
9 | * of the License. | 9 | * of the License. |
10 | */ | 10 | */ |
11 | #include <linux/moduleloader.h> | ||
12 | #include <asm/cacheflush.h> | ||
13 | #include <linux/netdevice.h> | 11 | #include <linux/netdevice.h> |
14 | #include <linux/filter.h> | 12 | #include <linux/filter.h> |
15 | #include <linux/if_vlan.h> | 13 | #include <linux/if_vlan.h> |
16 | #include <linux/random.h> | 14 | #include <asm/cacheflush.h> |
17 | 15 | ||
18 | int bpf_jit_enable __read_mostly; | 16 | int bpf_jit_enable __read_mostly; |
19 | 17 | ||
@@ -109,39 +107,6 @@ static inline void bpf_flush_icache(void *start, void *end) | |||
109 | #define CHOOSE_LOAD_FUNC(K, func) \ | 107 | #define CHOOSE_LOAD_FUNC(K, func) \ |
110 | ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) | 108 | ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) |
111 | 109 | ||
112 | struct bpf_binary_header { | ||
113 | unsigned int pages; | ||
114 | /* Note : for security reasons, bpf code will follow a randomly | ||
115 | * sized amount of int3 instructions | ||
116 | */ | ||
117 | u8 image[]; | ||
118 | }; | ||
119 | |||
120 | static struct bpf_binary_header *bpf_alloc_binary(unsigned int proglen, | ||
121 | u8 **image_ptr) | ||
122 | { | ||
123 | unsigned int sz, hole; | ||
124 | struct bpf_binary_header *header; | ||
125 | |||
126 | /* Most of BPF filters are really small, | ||
127 | * but if some of them fill a page, allow at least | ||
128 | * 128 extra bytes to insert a random section of int3 | ||
129 | */ | ||
130 | sz = round_up(proglen + sizeof(*header) + 128, PAGE_SIZE); | ||
131 | header = module_alloc(sz); | ||
132 | if (!header) | ||
133 | return NULL; | ||
134 | |||
135 | memset(header, 0xcc, sz); /* fill whole space with int3 instructions */ | ||
136 | |||
137 | header->pages = sz / PAGE_SIZE; | ||
138 | hole = min(sz - (proglen + sizeof(*header)), PAGE_SIZE - sizeof(*header)); | ||
139 | |||
140 | /* insert a random number of int3 instructions before BPF code */ | ||
141 | *image_ptr = &header->image[prandom_u32() % hole]; | ||
142 | return header; | ||
143 | } | ||
144 | |||
145 | /* pick a register outside of BPF range for JIT internal work */ | 110 | /* pick a register outside of BPF range for JIT internal work */ |
146 | #define AUX_REG (MAX_BPF_REG + 1) | 111 | #define AUX_REG (MAX_BPF_REG + 1) |
147 | 112 | ||
@@ -206,6 +171,12 @@ static inline u8 add_2reg(u8 byte, u32 dst_reg, u32 src_reg) | |||
206 | return byte + reg2hex[dst_reg] + (reg2hex[src_reg] << 3); | 171 | return byte + reg2hex[dst_reg] + (reg2hex[src_reg] << 3); |
207 | } | 172 | } |
208 | 173 | ||
174 | static void jit_fill_hole(void *area, unsigned int size) | ||
175 | { | ||
176 | /* fill whole space with int3 instructions */ | ||
177 | memset(area, 0xcc, size); | ||
178 | } | ||
179 | |||
209 | struct jit_context { | 180 | struct jit_context { |
210 | unsigned int cleanup_addr; /* epilogue code offset */ | 181 | unsigned int cleanup_addr; /* epilogue code offset */ |
211 | bool seen_ld_abs; | 182 | bool seen_ld_abs; |
@@ -959,7 +930,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog) | |||
959 | if (proglen <= 0) { | 930 | if (proglen <= 0) { |
960 | image = NULL; | 931 | image = NULL; |
961 | if (header) | 932 | if (header) |
962 | module_free(NULL, header); | 933 | bpf_jit_binary_free(header); |
963 | goto out; | 934 | goto out; |
964 | } | 935 | } |
965 | if (image) { | 936 | if (image) { |
@@ -969,7 +940,8 @@ void bpf_int_jit_compile(struct bpf_prog *prog) | |||
969 | break; | 940 | break; |
970 | } | 941 | } |
971 | if (proglen == oldproglen) { | 942 | if (proglen == oldproglen) { |
972 | header = bpf_alloc_binary(proglen, &image); | 943 | header = bpf_jit_binary_alloc(proglen, &image, |
944 | 1, jit_fill_hole); | ||
973 | if (!header) | 945 | if (!header) |
974 | goto out; | 946 | goto out; |
975 | } | 947 | } |
@@ -983,7 +955,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog) | |||
983 | bpf_flush_icache(header, image + proglen); | 955 | bpf_flush_icache(header, image + proglen); |
984 | set_memory_ro((unsigned long)header, header->pages); | 956 | set_memory_ro((unsigned long)header, header->pages); |
985 | prog->bpf_func = (void *)image; | 957 | prog->bpf_func = (void *)image; |
986 | prog->jited = 1; | 958 | prog->jited = true; |
987 | } | 959 | } |
988 | out: | 960 | out: |
989 | kfree(addrs); | 961 | kfree(addrs); |
@@ -998,7 +970,7 @@ void bpf_jit_free(struct bpf_prog *fp) | |||
998 | goto free_filter; | 970 | goto free_filter; |
999 | 971 | ||
1000 | set_memory_rw(addr, header->pages); | 972 | set_memory_rw(addr, header->pages); |
1001 | module_free(NULL, header); | 973 | bpf_jit_binary_free(header); |
1002 | 974 | ||
1003 | free_filter: | 975 | free_filter: |
1004 | bpf_prog_unlock_free(fp); | 976 | bpf_prog_unlock_free(fp); |
diff --git a/include/linux/filter.h b/include/linux/filter.h index 8f82ef3f1cdd..4b59edead908 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
@@ -289,15 +289,20 @@ struct sock_fprog_kern { | |||
289 | struct sock_filter *filter; | 289 | struct sock_filter *filter; |
290 | }; | 290 | }; |
291 | 291 | ||
292 | struct bpf_binary_header { | ||
293 | unsigned int pages; | ||
294 | u8 image[]; | ||
295 | }; | ||
296 | |||
292 | struct bpf_work_struct { | 297 | struct bpf_work_struct { |
293 | struct bpf_prog *prog; | 298 | struct bpf_prog *prog; |
294 | struct work_struct work; | 299 | struct work_struct work; |
295 | }; | 300 | }; |
296 | 301 | ||
297 | struct bpf_prog { | 302 | struct bpf_prog { |
298 | u32 pages; /* Number of allocated pages */ | 303 | u16 pages; /* Number of allocated pages */ |
299 | u32 jited:1, /* Is our filter JIT'ed? */ | 304 | bool jited; /* Is our filter JIT'ed? */ |
300 | len:31; /* Number of filter blocks */ | 305 | u32 len; /* Number of filter blocks */ |
301 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ | 306 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ |
302 | struct bpf_work_struct *work; /* Deferred free work struct */ | 307 | struct bpf_work_struct *work; /* Deferred free work struct */ |
303 | unsigned int (*bpf_func)(const struct sk_buff *skb, | 308 | unsigned int (*bpf_func)(const struct sk_buff *skb, |
@@ -358,6 +363,14 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size, | |||
358 | gfp_t gfp_extra_flags); | 363 | gfp_t gfp_extra_flags); |
359 | void __bpf_prog_free(struct bpf_prog *fp); | 364 | void __bpf_prog_free(struct bpf_prog *fp); |
360 | 365 | ||
366 | typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); | ||
367 | |||
368 | struct bpf_binary_header * | ||
369 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | ||
370 | unsigned int alignment, | ||
371 | bpf_jit_fill_hole_t bpf_fill_ill_insns); | ||
372 | void bpf_jit_binary_free(struct bpf_binary_header *hdr); | ||
373 | |||
361 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) | 374 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) |
362 | { | 375 | { |
363 | bpf_prog_unlock_ro(fp); | 376 | bpf_prog_unlock_ro(fp); |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 2c2bfaacce66..8ee520f0ec70 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
@@ -20,9 +20,12 @@ | |||
20 | * Andi Kleen - Fix a few bad bugs and races. | 20 | * Andi Kleen - Fix a few bad bugs and races. |
21 | * Kris Katterjohn - Added many additional checks in bpf_check_classic() | 21 | * Kris Katterjohn - Added many additional checks in bpf_check_classic() |
22 | */ | 22 | */ |
23 | |||
23 | #include <linux/filter.h> | 24 | #include <linux/filter.h> |
24 | #include <linux/skbuff.h> | 25 | #include <linux/skbuff.h> |
25 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/random.h> | ||
28 | #include <linux/moduleloader.h> | ||
26 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
27 | 30 | ||
28 | /* Registers */ | 31 | /* Registers */ |
@@ -125,6 +128,42 @@ void __bpf_prog_free(struct bpf_prog *fp) | |||
125 | } | 128 | } |
126 | EXPORT_SYMBOL_GPL(__bpf_prog_free); | 129 | EXPORT_SYMBOL_GPL(__bpf_prog_free); |
127 | 130 | ||
131 | struct bpf_binary_header * | ||
132 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | ||
133 | unsigned int alignment, | ||
134 | bpf_jit_fill_hole_t bpf_fill_ill_insns) | ||
135 | { | ||
136 | struct bpf_binary_header *hdr; | ||
137 | unsigned int size, hole, start; | ||
138 | |||
139 | /* Most of BPF filters are really small, but if some of them | ||
140 | * fill a page, allow at least 128 extra bytes to insert a | ||
141 | * random section of illegal instructions. | ||
142 | */ | ||
143 | size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE); | ||
144 | hdr = module_alloc(size); | ||
145 | if (hdr == NULL) | ||
146 | return NULL; | ||
147 | |||
148 | /* Fill space with illegal/arch-dep instructions. */ | ||
149 | bpf_fill_ill_insns(hdr, size); | ||
150 | |||
151 | hdr->pages = size / PAGE_SIZE; | ||
152 | hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)), | ||
153 | PAGE_SIZE - sizeof(*hdr)); | ||
154 | start = (prandom_u32() % hole) & ~(alignment - 1); | ||
155 | |||
156 | /* Leave a random number of instructions before BPF code. */ | ||
157 | *image_ptr = &hdr->image[start]; | ||
158 | |||
159 | return hdr; | ||
160 | } | ||
161 | |||
162 | void bpf_jit_binary_free(struct bpf_binary_header *hdr) | ||
163 | { | ||
164 | module_free(NULL, hdr); | ||
165 | } | ||
166 | |||
128 | /* Base function for offset calculation. Needs to go into .text section, | 167 | /* Base function for offset calculation. Needs to go into .text section, |
129 | * therefore keeping it non-static as well; will also be used by JITs | 168 | * therefore keeping it non-static as well; will also be used by JITs |
130 | * anyway later on, so do not let the compiler omit it. | 169 | * anyway later on, so do not let the compiler omit it. |
diff --git a/net/core/filter.c b/net/core/filter.c index fa5b7d0f77ac..dfc716ffa44b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -972,7 +972,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp) | |||
972 | int err; | 972 | int err; |
973 | 973 | ||
974 | fp->bpf_func = NULL; | 974 | fp->bpf_func = NULL; |
975 | fp->jited = 0; | 975 | fp->jited = false; |
976 | 976 | ||
977 | err = bpf_check_classic(fp->insns, fp->len); | 977 | err = bpf_check_classic(fp->insns, fp->len); |
978 | if (err) { | 978 | if (err) { |