aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/sock_map.c')
-rw-r--r--net/core/sock_map.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 52d4faeee18b..1330a7442e5b 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -247,6 +247,8 @@ static void sock_map_free(struct bpf_map *map)
247 raw_spin_unlock_bh(&stab->lock); 247 raw_spin_unlock_bh(&stab->lock);
248 rcu_read_unlock(); 248 rcu_read_unlock();
249 249
250 synchronize_rcu();
251
250 bpf_map_area_free(stab->sks); 252 bpf_map_area_free(stab->sks);
251 kfree(stab); 253 kfree(stab);
252} 254}
@@ -276,16 +278,20 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test,
276 struct sock **psk) 278 struct sock **psk)
277{ 279{
278 struct sock *sk; 280 struct sock *sk;
281 int err = 0;
279 282
280 raw_spin_lock_bh(&stab->lock); 283 raw_spin_lock_bh(&stab->lock);
281 sk = *psk; 284 sk = *psk;
282 if (!sk_test || sk_test == sk) 285 if (!sk_test || sk_test == sk)
283 *psk = NULL; 286 sk = xchg(psk, NULL);
287
288 if (likely(sk))
289 sock_map_unref(sk, psk);
290 else
291 err = -EINVAL;
292
284 raw_spin_unlock_bh(&stab->lock); 293 raw_spin_unlock_bh(&stab->lock);
285 if (unlikely(!sk)) 294 return err;
286 return -EINVAL;
287 sock_map_unref(sk, psk);
288 return 0;
289} 295}
290 296
291static void sock_map_delete_from_link(struct bpf_map *map, struct sock *sk, 297static void sock_map_delete_from_link(struct bpf_map *map, struct sock *sk,
@@ -328,6 +334,7 @@ static int sock_map_update_common(struct bpf_map *map, u32 idx,
328 struct sock *sk, u64 flags) 334 struct sock *sk, u64 flags)
329{ 335{
330 struct bpf_stab *stab = container_of(map, struct bpf_stab, map); 336 struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
337 struct inet_connection_sock *icsk = inet_csk(sk);
331 struct sk_psock_link *link; 338 struct sk_psock_link *link;
332 struct sk_psock *psock; 339 struct sk_psock *psock;
333 struct sock *osk; 340 struct sock *osk;
@@ -338,6 +345,8 @@ static int sock_map_update_common(struct bpf_map *map, u32 idx,
338 return -EINVAL; 345 return -EINVAL;
339 if (unlikely(idx >= map->max_entries)) 346 if (unlikely(idx >= map->max_entries))
340 return -E2BIG; 347 return -E2BIG;
348 if (unlikely(icsk->icsk_ulp_data))
349 return -EINVAL;
341 350
342 link = sk_psock_init_link(); 351 link = sk_psock_init_link();
343 if (!link) 352 if (!link)