Currently we check sk_user_data is non NULL to determine if the sk
exists in a map. However, this is not sufficient to ensure the psock
is not in use by another (non-ULP TCP) user, such as kcm. To avoid
this when adding a sock to a map also verify it is of the correct ULP
type.

Signed-off-by: John Fastabend <john.fastab...@gmail.com>
---
 0 files changed

diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index ce63e58..1c05794 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -1808,6 +1808,11 @@ static int sock_map_delete_elem(struct bpf_map *map, 
void *key)
        return 0;
 }
 
+static bool psock_is_smap_sk(struct sock *sk)
+{
+       return inet_csk(sk)->icsk_ulp_ops == &bpf_tcp_ulp_ops;
+}
+
 /* Locking notes: Concurrent updates, deletes, and lookups are allowed and are
  * done inside rcu critical sections. This ensures on updates that the psock
  * will not be released via smap_release_sock() until concurrent 
updates/deletes
@@ -1892,6 +1897,10 @@ static int __sock_map_ctx_update_elem(struct bpf_map 
*map,
         * doesn't update user data.
         */
        if (psock) {
+               if (!psock_is_smap_sk(sock)) {
+                       err = -EBUSY;
+                       goto out_progs;
+               }
                if (READ_ONCE(psock->bpf_parse) && parse) {
                        err = -EBUSY;
                        goto out_progs;

Reply via email to