Commit 85b8ac0
bpf, sockmap: Check update requirements after locking
It's currently possible to insert sockets in unexpected states into
a sockmap, due to a TOCTTOU when updating the map from a syscall.
sock_map_update_elem checks that sk->sk_state == TCP_ESTABLISHED,
locks the socket and then calls sock_map_update_common. At this
point, the socket may have transitioned into another state, and
the earlier assumptions don't hold anymore. Crucially, it's
conceivable (though very unlikely) that a socket has become unhashed.
This breaks the sockmap's assumption that it will get a callback
via sk->sk_prot->unhash.
Fix this by checking the (fixed) sk_type and sk_protocol without the
lock, followed by a locked check of sk_state.
Unfortunately it's not possible to push the check down into
sock_(map|hash)_update_common, since BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB
run before the socket has transitioned from TCP_SYN_RECV into
TCP_ESTABLISHED.
Fixes: 604326b ("bpf, sockmap: convert to generic sk_msg interface")
Signed-off-by: Lorenz Bauer <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Reviewed-by: Jakub Sitnicki <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]1 parent b9e4272 commit 85b8ac0
1 file changed
+10
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
416 | 416 | | |
417 | 417 | | |
418 | 418 | | |
419 | | - | |
420 | | - | |
| 419 | + | |
421 | 420 | | |
422 | 421 | | |
423 | 422 | | |
424 | 423 | | |
425 | 424 | | |
426 | | - | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
427 | 429 | | |
428 | 430 | | |
429 | 431 | | |
| |||
739 | 741 | | |
740 | 742 | | |
741 | 743 | | |
742 | | - | |
743 | | - | |
| 744 | + | |
744 | 745 | | |
745 | 746 | | |
746 | 747 | | |
747 | 748 | | |
748 | 749 | | |
749 | | - | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
750 | 754 | | |
751 | 755 | | |
752 | 756 | | |
| |||
0 commit comments