• Nicolas Schichan's avatar
    ARM: net: delegate filter to kernel interpreter when imm_offset() return value... · 0b59d880
    Nicolas Schichan authored
    ARM: net: delegate filter to kernel interpreter when imm_offset() return value can't fit into 12bits.
    
    The ARM JIT code emits "ldr rX, [pc, #offset]" to access the literal
    pool. #offset maximum value is 4095 and if the generated code is too
    large, the #offset value can overflow and not point to the expected
    slot in the literal pool. Additionally, when overflow occurs, bits of
    the overflow can end up changing the destination register of the ldr
    instruction.
    
    Fix that by detecting the overflow in imm_offset() and setting a flag
    that is checked for each BPF instructions converted in
    build_body(). As of now it can only be detected in the second pass. As
    a result the second build_body() call can now fail, so add the
    corresponding cleanup code in that case.
    
    Using multiple literal pools in the JITed code is going to require
    lots of intrusive changes to the JIT code (which would better be done
    as a feature instead of fix), just delegating to the kernel BPF
    interpreter in that case is a more straight forward, minimal fix and
    easy to backport.
    
    Fixes: ddecdfce ("ARM: 7259/3: net: JIT compiler for packet filters")
    Signed-off-by: default avatarNicolas Schichan <nschichan@freebox.fr>
    Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0b59d880
bpf_jit_32.c 24.2 KB