• Daniel Borkmann's avatar
    net: bpf: arm: make hole-faulting more robust · e8b56d55
    Daniel Borkmann authored
    Will Deacon pointed out, that the currently used opcode for filling holes,
    that is 0xe7ffffff, seems not robust enough ...
    
      $ echo 0xffffffe7 | xxd -r > test.bin
      $ arm-linux-gnueabihf-objdump -m arm -D -b binary test.bin
      ...
      0: e7ffffff     udf    #65535  ; 0xffff
    
    ... while for Thumb, it ends up as ...
    
      0: ffff e7ff    vqshl.u64  q15, <illegal reg q15.5>, #63
    
    ... which is a bit fragile. The ARM specification defines some *permanently*
    guaranteed undefined instruction (UDF) space, for example for ARM in ARMv7-AR,
    section A5.4 and for Thumb in ARMv7-M, section A5.2.6.
    
    Similarly, ptrace, kprobes, kgdb, bug and uprobes make use of such instruction
    as well to trap. Given mentioned section from the specification, we can find
    such a universe as (where 'x' denotes 'don't care'):
    
      ARM:    xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
      Thumb:  1101 1110 xxxx xxxx
    
    We therefore should use a more robust opcode that fits both. Russell King
    suggested that we can even reuse a single 32-bit word, that is, 0xe7fddef1
    which will fault if executed in ARM *or* Thumb mode as done in f928d4f2
    ("ARM: poison the vectors page"). That will still hold our requirements:
    
      $ echo 0xf1defde7 | xxd -r > test.bin
      $ arm-unknown-linux-gnueabi-objdump -m arm -D -b binary test.bin
      ...
      0: e7fddef1     udf    #56801 ; 0xdde1
      $ echo 0xf1defde7f1defde7f1defde7 | xxd -r > test.bin
      $ arm-unknown-linux-gnueabi-objdump -marm -Mforce-thumb -D -b binary test.bin
      ...
      0: def1         udf    #241 ; 0xf1
      2: e7fd         b.n    0x0
      4: def1         udf    #241 ; 0xf1
      6: e7fd         b.n    0x4
      8: def1         udf    #241 ; 0xf1
      a: e7fd         b.n    0x8
    
    So on ARM 0xe7fddef1 conforms to the above UDF pattern, and the low 16 bit
    likewise correspond to UDF in Thumb case. The 0xe7fd part is an unconditional
    branch back to the UDF instruction.
    Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
    Cc: Russell King <linux@arm.linux.org.uk>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Will Deacon <will.deacon@arm.com>
    Cc: Mircea Gherzan <mgherzan@gmail.com>
    Cc: Alexei Starovoitov <ast@plumgrid.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e8b56d55
bpf_jit_32.c 23.3 KB