aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/net
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2012-03-17 22:40:48 -0400
committerDavid S. Miller <davem@davemloft.net>2012-03-19 17:41:44 -0400
commitdc72d99dabb870ca5bd6d9fff674be853bb4a88d (patch)
tree20fbc871a5f19e4e243425d78c5a2e50cbb66912 /arch/x86/net
parent3af79302b400e05b45e377993a8870869500466b (diff)
net: bpf_jit: fix BPF_S_LDX_B_MSH compilation
Matt Evans spotted that x86 bpf_jit was incorrectly handling negative constant offsets in BPF_S_LDX_B_MSH instruction. We need to abort JIT compilation like we do in common_load so that filter uses the interpreter code and can call __load_pointer() Reference: http://lists.openwall.net/netdev/2011/07/19/11 Thanks to Indan Zupancic to bring back this issue. Reported-by: Matt Evans <matt@ozlabs.org> Reported-by: Indan Zupancic <indan@nul.nu> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/x86/net')
-rw-r--r--arch/x86/net/bpf_jit_comp.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 7c1b765ecc59..5671752f8d9c 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -475,8 +475,10 @@ void bpf_jit_compile(struct sk_filter *fp)
475 case BPF_S_LD_W_ABS: 475 case BPF_S_LD_W_ABS:
476 func = sk_load_word; 476 func = sk_load_word;
477common_load: seen |= SEEN_DATAREF; 477common_load: seen |= SEEN_DATAREF;
478 if ((int)K < 0) 478 if ((int)K < 0) {
479 /* Abort the JIT because __load_pointer() is needed. */
479 goto out; 480 goto out;
481 }
480 t_offset = func - (image + addrs[i]); 482 t_offset = func - (image + addrs[i]);
481 EMIT1_off32(0xbe, K); /* mov imm32,%esi */ 483 EMIT1_off32(0xbe, K); /* mov imm32,%esi */
482 EMIT1_off32(0xe8, t_offset); /* call */ 484 EMIT1_off32(0xe8, t_offset); /* call */
@@ -489,14 +491,8 @@ common_load: seen |= SEEN_DATAREF;
489 goto common_load; 491 goto common_load;
490 case BPF_S_LDX_B_MSH: 492 case BPF_S_LDX_B_MSH:
491 if ((int)K < 0) { 493 if ((int)K < 0) {
492 if (pc_ret0 > 0) { 494 /* Abort the JIT because __load_pointer() is needed. */
493 /* addrs[pc_ret0 - 1] is the start address */ 495 goto out;
494 EMIT_JMP(addrs[pc_ret0 - 1] - addrs[i]);
495 break;
496 }
497 CLEAR_A();
498 EMIT_JMP(cleanup_addr - addrs[i]);
499 break;
500 } 496 }
501 seen |= SEEN_DATAREF | SEEN_XREG; 497 seen |= SEEN_DATAREF | SEEN_XREG;
502 t_offset = sk_load_byte_msh - (image + addrs[i]); 498 t_offset = sk_load_byte_msh - (image + addrs[i]);