diff options
author | Zi Shen Lim <zlim.lnx@gmail.com> | 2015-11-18 03:56:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-11-18 22:38:11 -0500 |
commit | f4b16fce7a5a1ec8069b1f577476bdc1d2688cd1 (patch) | |
tree | cb92644a31a75baf9ff434899a44ffbad0a5d8b3 | |
parent | 508dc0648ca8a2d305faee472cea5e0be579014f (diff) |
arm64: bpf: fix buffer pointer
During code review, I noticed we were passing a bad buffer pointer
to bpf_load_pointer helper function called by jitted code.
Point to the buffer allocated by JIT, so we don't silently corrupt
other parts of the stack.
Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com>
Acked-by: Yang Shi <yang.shi@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/arm64/net/bpf_jit_comp.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index d6a53ef2350b..7cf032bebf8c 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c | |||
@@ -139,6 +139,12 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) | |||
139 | /* Stack must be multiples of 16B */ | 139 | /* Stack must be multiples of 16B */ |
140 | #define STACK_ALIGN(sz) (((sz) + 15) & ~15) | 140 | #define STACK_ALIGN(sz) (((sz) + 15) & ~15) |
141 | 141 | ||
142 | #define _STACK_SIZE \ | ||
143 | (MAX_BPF_STACK \ | ||
144 | + 4 /* extra for skb_copy_bits buffer */) | ||
145 | |||
146 | #define STACK_SIZE STACK_ALIGN(_STACK_SIZE) | ||
147 | |||
142 | static void build_prologue(struct jit_ctx *ctx) | 148 | static void build_prologue(struct jit_ctx *ctx) |
143 | { | 149 | { |
144 | const u8 r6 = bpf2a64[BPF_REG_6]; | 150 | const u8 r6 = bpf2a64[BPF_REG_6]; |
@@ -150,10 +156,6 @@ static void build_prologue(struct jit_ctx *ctx) | |||
150 | const u8 rx = bpf2a64[BPF_REG_X]; | 156 | const u8 rx = bpf2a64[BPF_REG_X]; |
151 | const u8 tmp1 = bpf2a64[TMP_REG_1]; | 157 | const u8 tmp1 = bpf2a64[TMP_REG_1]; |
152 | const u8 tmp2 = bpf2a64[TMP_REG_2]; | 158 | const u8 tmp2 = bpf2a64[TMP_REG_2]; |
153 | int stack_size = MAX_BPF_STACK; | ||
154 | |||
155 | stack_size += 4; /* extra for skb_copy_bits buffer */ | ||
156 | stack_size = STACK_ALIGN(stack_size); | ||
157 | 159 | ||
158 | /* | 160 | /* |
159 | * BPF prog stack layout | 161 | * BPF prog stack layout |
@@ -165,12 +167,13 @@ static void build_prologue(struct jit_ctx *ctx) | |||
165 | * | ... | callee saved registers | 167 | * | ... | callee saved registers |
166 | * +-----+ | 168 | * +-----+ |
167 | * | | x25/x26 | 169 | * | | x25/x26 |
168 | * BPF fp register => -80:+-----+ | 170 | * BPF fp register => -80:+-----+ <= (BPF_FP) |
169 | * | | | 171 | * | | |
170 | * | ... | BPF prog stack | 172 | * | ... | BPF prog stack |
171 | * | | | 173 | * | | |
172 | * | | | 174 | * +-----+ <= (BPF_FP - MAX_BPF_STACK) |
173 | * current A64_SP => +-----+ | 175 | * |RSVD | JIT scratchpad |
176 | * current A64_SP => +-----+ <= (BPF_FP - STACK_SIZE) | ||
174 | * | | | 177 | * | | |
175 | * | ... | Function call stack | 178 | * | ... | Function call stack |
176 | * | | | 179 | * | | |
@@ -196,7 +199,7 @@ static void build_prologue(struct jit_ctx *ctx) | |||
196 | emit(A64_MOV(1, fp, A64_SP), ctx); | 199 | emit(A64_MOV(1, fp, A64_SP), ctx); |
197 | 200 | ||
198 | /* Set up function call stack */ | 201 | /* Set up function call stack */ |
199 | emit(A64_SUB_I(1, A64_SP, A64_SP, stack_size), ctx); | 202 | emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); |
200 | 203 | ||
201 | /* Clear registers A and X */ | 204 | /* Clear registers A and X */ |
202 | emit_a64_mov_i64(ra, 0, ctx); | 205 | emit_a64_mov_i64(ra, 0, ctx); |
@@ -213,13 +216,9 @@ static void build_epilogue(struct jit_ctx *ctx) | |||
213 | const u8 fp = bpf2a64[BPF_REG_FP]; | 216 | const u8 fp = bpf2a64[BPF_REG_FP]; |
214 | const u8 tmp1 = bpf2a64[TMP_REG_1]; | 217 | const u8 tmp1 = bpf2a64[TMP_REG_1]; |
215 | const u8 tmp2 = bpf2a64[TMP_REG_2]; | 218 | const u8 tmp2 = bpf2a64[TMP_REG_2]; |
216 | int stack_size = MAX_BPF_STACK; | ||
217 | |||
218 | stack_size += 4; /* extra for skb_copy_bits buffer */ | ||
219 | stack_size = STACK_ALIGN(stack_size); | ||
220 | 219 | ||
221 | /* We're done with BPF stack */ | 220 | /* We're done with BPF stack */ |
222 | emit(A64_ADD_I(1, A64_SP, A64_SP, stack_size), ctx); | 221 | emit(A64_ADD_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); |
223 | 222 | ||
224 | /* Restore fs (x25) and x26 */ | 223 | /* Restore fs (x25) and x26 */ |
225 | emit(A64_POP(fp, A64_R(26), A64_SP), ctx); | 224 | emit(A64_POP(fp, A64_R(26), A64_SP), ctx); |
@@ -658,7 +657,7 @@ emit_cond_jmp: | |||
658 | return -EINVAL; | 657 | return -EINVAL; |
659 | } | 658 | } |
660 | emit_a64_mov_i64(r3, size, ctx); | 659 | emit_a64_mov_i64(r3, size, ctx); |
661 | emit(A64_ADD_I(1, r4, fp, MAX_BPF_STACK), ctx); | 660 | emit(A64_SUB_I(1, r4, fp, STACK_SIZE), ctx); |
662 | emit_a64_mov_i64(r5, (unsigned long)bpf_load_pointer, ctx); | 661 | emit_a64_mov_i64(r5, (unsigned long)bpf_load_pointer, ctx); |
663 | emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); | 662 | emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); |
664 | emit(A64_MOV(1, A64_FP, A64_SP), ctx); | 663 | emit(A64_MOV(1, A64_FP, A64_SP), ctx); |