bpf: support decreasing order in direct packet access
authorAlexei Starovoitov <ast@fb.com>
Fri, 20 May 2016 01:17:13 +0000 (18:17 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 May 2016 23:53:03 +0000 (19:53 -0400)
commitd91b28ed42de99217efb2e8cb0357263d6fb737c
treeb75e365810041e821fbcfe0824e18aef0e36820e
parent238a9584e9e2c7b3ea23924e9183fee05d584789
bpf: support decreasing order in direct packet access

when packet headers are accessed in 'decreasing' order (like TCP port
may be fetched before the program reads IP src) the llvm may generate
the following code:
[...]                // R7=pkt(id=0,off=22,r=70)
r2 = *(u32 *)(r7 +0) // good access
[...]
r7 += 40             // R7=pkt(id=0,off=62,r=70)
r8 = *(u32 *)(r7 +0) // good access
[...]
r1 = *(u32 *)(r7 -20) // this one will fail though it's within a safe range
                      // it's doing *(u32*)(skb->data + 42)
Fix verifier to recognize such code pattern

Alos turned out that 'off > range' condition is not a verifier bug.
It's a buggy program that may do something like:
if (ptr + 50 > data_end)
  return 0;
ptr += 60;
*(u32*)ptr;
in such case emit
"invalid access to packet, off=0 size=4, R1(id=0,off=60,r=50)" error message,
so all information is available for the program author to fix the program.

Fixes: 969bf05eb3ce ("bpf: direct packet access")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
kernel/bpf/verifier.c