[bpf] Fix memory offset check for loads and stores
authorAlexei Starovoitov <alexei.starovoitov@gmail.com>
Thu, 13 Apr 2017 22:24:13 +0000 (22:24 +0000)
committerAlexei Starovoitov <alexei.starovoitov@gmail.com>
Thu, 13 Apr 2017 22:24:13 +0000 (22:24 +0000)
commit56db14516450f980e69034f7d8a7be1e1f133c52
treef1bfc66959ebdc5a60b7b5407349684f6129727d
parente6185b70e93b16350b3cc4e82e2a809ce41dcd9b
[bpf] Fix memory offset check for loads and stores

If the offset cannot fit into the instruction, an addition to the
pointer is emitted before the actual access. However, BPF offsets are
16-bit but LLVM considers them to be, for the matter of this check,
to be 32-bit long.

This causes the following program:

int bpf_prog1(void *ign)
{

volatile unsigned long t = 0x8983984739ull;
return *(unsigned long *)((0xffffffff8fff0002ull) + t);

}

To generate the following (wrong) code:

0: 18 01 00 00 39 47 98 83 00 00 00 00 89 00 00 00

r1 = 590618314553ll

2: 7b 1a f8 ff 00 00 00 00 *(u64 *)(r10 - 8) = r1
3: 79 a1 f8 ff 00 00 00 00 r1 = *(u64 *)(r10 - 8)
4: 79 10 02 00 00 00 00 00 r0 = *(u64 *)(r1 + 2)
5: 95 00 00 00 00 00 00 00 exit

Fix it by changing the offset check to 16-bit.

Patch by Nadav Amit <nadav.amit@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Differential Revision: https://reviews.llvm.org/D32055

llvm-svn: 300269
llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
llvm/test/CodeGen/BPF/mem_offset.ll [new file with mode: 0644]