bpf: Fix the off-by-two error in range markings
authorMaxim Mikityanskiy <maximmi@nvidia.com>
Tue, 30 Nov 2021 18:16:07 +0000 (20:16 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 3 Dec 2021 20:44:42 +0000 (21:44 +0100)
commit2fa7d94afc1afbb4d702760c058dc2d7ed30f226
treeff22462c475dfa3a0f85702e2b1ae83cbfe5b3cc
parent8581fd402a0cf80b5298e3b225e7a7bd8f110e69
bpf: Fix the off-by-two error in range markings

The first commit cited below attempts to fix the off-by-one error that
appeared in some comparisons with an open range. Due to this error,
arithmetically equivalent pieces of code could get different verdicts
from the verifier, for example (pseudocode):

  // 1. Passes the verifier:
  if (data + 8 > data_end)
      return early
  read *(u64 *)data, i.e. [data; data+7]

  // 2. Rejected by the verifier (should still pass):
  if (data + 7 >= data_end)
      return early
  read *(u64 *)data, i.e. [data; data+7]

The attempted fix, however, shifts the range by one in a wrong
direction, so the bug not only remains, but also such piece of code
starts failing in the verifier:

  // 3. Rejected by the verifier, but the check is stricter than in #1.
  if (data + 8 >= data_end)
      return early
  read *(u64 *)data, i.e. [data; data+7]

The change performed by that fix converted an off-by-one bug into
off-by-two. The second commit cited below added the BPF selftests
written to ensure than code chunks like #3 are rejected, however,
they should be accepted.

This commit fixes the off-by-two error by adjusting new_range in the
right direction and fixes the tests by changing the range into the
one that should actually fail.

Fixes: fb2a311a31d3 ("bpf: fix off by one for range markings with L{T, E} patterns")
Fixes: b37242c773b2 ("bpf: add test cases to bpf selftests to cover all access tests")
Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20211130181607.593149-1-maximmi@nvidia.com
kernel/bpf/verifier.c
tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c