On 4/24/19 12:49 PM, Paul Chaignon wrote: > In case of a null check on a pointer inside a subprog, we should mark all > registers with this pointer as either safe or unknown, in both the current > and previous frames. Currently, only spilled registers and registers in > the current frame are marked. Packet bound checks in subprogs have the > same issue. The first patch fixes it to mark registers in previous frames > as well. > > A good reproducer for null checks looks as follow: > > 1: ptr = bpf_map_lookup_elem(map, &key); > 2: ret = subprog(ptr) { > 3: return ptr != NULL; > 4: } > 5: if (ret) > 6: value = *ptr; > > With the above, the verifier will complain on line 6 because it sees ptr > as map_value_or_null despite the null check in subprog 1. The second > patch implements the above as a new test case. > > Note that this patch fixes another resulting bug when using > bpf_sk_release(): > > 1: sk = bpf_sk_lookup_tcp(...); > 2: subprog(sk) { > 3: if (sk) > 4: bpf_sk_release(sk); > 5: } > 6: if (!sk) > 7: return 0; > 8: return 1; > > In the above, mark_ptr_or_null_regs will warn on line 6 because it will > try to free the reference state, even though it was already freed on > line 3. > > Changelogs: > Changes in v3: > - Fix same issue in find_good_pkt_pointers(). > - Add test case for find_good_pkt_pointers() issue. > - Change title to account for the above change. Old title was > "bpf: mark registers as safe or unknown in all frames". > - Refactor find_good_pkt_pointers and mark_ptr_or_null_regs. > - I did not keep Yonghong's ack because of the above changes. > Changes in v2: > - Fix example codes in commit message. > > Paul Chaignon (2): > bpf: mark registers in all frames after pkt/null checks > selftests/bpf: test cases for pkt/null checks in subprogs > > kernel/bpf/verifier.c | 76 +++++++++++-------- > tools/testing/selftests/bpf/verifier/calls.c | 25 ++++++ > .../bpf/verifier/direct_packet_access.c | 22 ++++++ > 3 files changed, 93 insertions(+), 30 deletions(-) Ack for the whole series. Acked-by: Yonghong Song <yhs@xxxxxx>