aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-09 19:59:03 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-09 19:59:03 -0400
commit60005c60b1ea807013bcbbfe9309fc924a3881f0 (patch)
tree50f1a085ddd7923b2b3c2764c850d0c02447d32a
parentca777eff51f7fbaebd954e645d8ecb781a906b4a (diff)
parent286aad3c4014ca825c447e07e24f8929e6d266d2 (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.c34
-rw-r--r--arch/mips/net/bpf_jit.c2
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c2
-rw-r--r--arch/s390/net/bpf_jit_comp.c47
-rw-r--r--arch/sparc/net/bpf_jit_comp.c2
-rw-r--r--arch/x86/net/bpf_jit_comp.c52
-rw-r--r--include/linux/filter.h19
-rw-r--r--kernel/bpf/core.c39
-rw-r--r--net/core/filter.c2
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
176static 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
177static void build_prologue(struct jit_ctx *ctx) 185static 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
860void bpf_jit_compile(struct bpf_prog *fp) 868void 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;
924out: 937out:
925 kfree(ctx.offsets); 938 kfree(ctx.offsets);
926 return; 939 return;
@@ -928,8 +941,15 @@ out:
928 941
929void bpf_jit_free(struct bpf_prog *fp) 942void 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
953free_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
1422out: 1422out:
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 }
691out: 691out:
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
149static 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
151static void bpf_jit_prologue(struct bpf_jit *jit) 155static 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 */
787struct bpf_binary_header {
788 unsigned int pages;
789 u8 image[];
790};
791
792static 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
815void bpf_jit_compile(struct bpf_prog *fp) 787void 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 }
874out: 847out:
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
889free_filter: 862free_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 }
806out: 806out:
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
18int bpf_jit_enable __read_mostly; 16int 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
112struct 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
120static 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
174static void jit_fill_hole(void *area, unsigned int size)
175{
176 /* fill whole space with int3 instructions */
177 memset(area, 0xcc, size);
178}
179
209struct jit_context { 180struct 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 }
988out: 960out:
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
1003free_filter: 975free_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
292struct bpf_binary_header {
293 unsigned int pages;
294 u8 image[];
295};
296
292struct bpf_work_struct { 297struct 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
297struct bpf_prog { 302struct 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);
359void __bpf_prog_free(struct bpf_prog *fp); 364void __bpf_prog_free(struct bpf_prog *fp);
360 365
366typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
367
368struct bpf_binary_header *
369bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
370 unsigned int alignment,
371 bpf_jit_fill_hole_t bpf_fill_ill_insns);
372void bpf_jit_binary_free(struct bpf_binary_header *hdr);
373
361static inline void bpf_prog_unlock_free(struct bpf_prog *fp) 374static 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}
126EXPORT_SYMBOL_GPL(__bpf_prog_free); 129EXPORT_SYMBOL_GPL(__bpf_prog_free);
127 130
131struct bpf_binary_header *
132bpf_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
162void 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) {