Page MenuHomePhabricator

[bpf] Fix memory offset check for loads and stores
ClosedPublic

Authored by ast on Apr 13 2017, 2:46 PM.

Details

Summary

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.

Diff Detail

Repository
rL LLVM

Event Timeline

namit created this revision.Apr 13 2017, 2:46 PM
ast accepted this revision.Apr 13 2017, 3:07 PM
This revision is now accepted and ready to land.Apr 13 2017, 3:07 PM
ast commandeered this revision.Apr 13 2017, 3:10 PM
ast edited reviewers, added: namit; removed: ast.
This revision now requires review to proceed.Apr 13 2017, 3:10 PM
ast accepted this revision.Apr 13 2017, 3:10 PM
This revision is now accepted and ready to land.Apr 13 2017, 3:10 PM
This revision was automatically updated to reflect the committed changes.