-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix map value pruning check #4010
Conversation
Upstream branch: 4b45cd8 |
6e40182
to
526689d
Compare
Upstream branch: 4b45cd8 |
5151e5c
to
1f48e6b
Compare
526689d
to
a14bc27
Compare
Upstream branch: 1f6e04a |
1f48e6b
to
dd06e46
Compare
a14bc27
to
07ca343
Compare
Upstream branch: 9cbd48d |
dd06e46
to
a9976cd
Compare
07ca343
to
96140d3
Compare
Upstream branch: ed1fe1b |
a9976cd
to
51a1dde
Compare
96140d3
to
5e4048b
Compare
Upstream branch: 5fd2a60 |
51a1dde
to
96dbfa9
Compare
5e4048b
to
03aa0c5
Compare
Upstream branch: 47df8a2 |
96dbfa9
to
4fee0bb
Compare
03aa0c5
to
5f4c504
Compare
Upstream branch: 47df8a2 |
4fee0bb
to
cdc09cb
Compare
5f4c504
to
f0479c3
Compare
Upstream branch: 6f04180 |
cdc09cb
to
a23ad0a
Compare
f0479c3
to
93695cf
Compare
Upstream branch: 11a695a |
a23ad0a
to
59737c6
Compare
93695cf
to
881fc52
Compare
Upstream branch: 8be602d |
59737c6
to
5f7682a
Compare
881fc52
to
0ebdd29
Compare
Currently, the verifier preserves reg->id for PTR_TO_MAP_VALUE when it points to a map value that contains a bpf_spin_lock element (see the logic in reg_may_point_to_spin_lock and how it is used to skip setting reg->id to 0 in mark_ptr_or_null_reg). This gives a unique lock ID for each critical section begun by a bpf_spin_lock helper call. The same reg->id is matched with env->active_spin_lock during unlock to determine whether bpf_spin_unlock is called for the same bpf_spin_lock object. However, regsafe takes a different approach to safety checks currently. The comparison of reg->id was explicitly skipped in the commit being fixed with the reasoning that the reg->id value should have no bearing on the safety of the program if the old state was verified to be safe. This however is demonstrably not true (with a selftest having the verbose working test case in a later commit), with the following pseudo code: r0 = bpf_map_lookup_elem(&map, ...); // id=1 r6 = r0; r0 = bpf_map_lookup_elem(&map, ...); // id=2 r7 = r0; bpf_spin_lock(r1=r6); if (cond) // unknown scalar, hence verifier cannot predict branch r6 = r7; p: bpf_spin_unlock(r1=r7); In the first exploration path, we would want the verifier to skip over the r6 = r7 assignment so that it reaches BPF_EXIT and the state branches counter drops to 0 and it becomes a safe verified state. The branch target 'p' acts a pruning point, hence states will be compared. If the old state was verified without assignment, it has r6 with id=1, but the new state will have r6 with id=2. The other parts of register, stack, and reference state and any other verifier state compared in states_equal remain unaffected by the assignment. Now, when the memcmp fails for r6, the verifier drops to the switch case and simply memcmp until the id member, and requires the var_off to be more permissive in the current state. Once establishing this fact, it returns true and search is pruned. Essentially, we end up calling unlock for a bpf_spin_lock that was never locked whenever the condition is true at runtime. To fix this, also include id in the memcmp comparison. Since ref_obj_id is never set for PTR_TO_MAP_VALUE, change the offsetof to be until that member. Note that by default the reg->id in case of PTR_TO_MAP_VALUE should be 0 (without PTR_MAYBE_NULL), so it should only really impact cases where a bpf_spin_lock is present in the map element. Fixes: d83525c ("bpf: introduce bpf_spin_lock") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Stanislav Fomichev <sdf@google.com>
Upstream branch: 8be602d |
Test that when reg->id is not same for the same register of type PTR_TO_MAP_VALUE between current and old explored state, we currently return false from regsafe and continue exploring. Without the fix in prior commit, the test case fails. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Stanislav Fomichev <sdf@google.com>
5f7682a
to
41020cf
Compare
At least one diff in series https://patchwork.kernel.org/project/netdevbpf/list/?series=694607 expired. Closing PR. |
Pull request for series with
subject: Fix map value pruning check
version: 1
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=694607