Skip to content

Commit 3a5d1c0

Browse files
Eric Dumazetdavem330
authored andcommitted
inet: reqsk_alloc() needs to take care of dead listeners
We'll soon no longer take a refcount on listeners, so reqsk_alloc() can not assume a listener refcount is not zero. We need to use atomic_inc_not_zero() Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2d33191 commit 3a5d1c0

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

include/net/request_sock.h

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,23 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
8585
struct request_sock *req;
8686

8787
req = kmem_cache_alloc(ops->slab, GFP_ATOMIC | __GFP_NOWARN);
88-
89-
if (req) {
90-
req->rsk_ops = ops;
91-
if (attach_listener) {
92-
sock_hold(sk_listener);
93-
req->rsk_listener = sk_listener;
94-
} else {
95-
req->rsk_listener = NULL;
88+
if (!req)
89+
return NULL;
90+
req->rsk_listener = NULL;
91+
if (attach_listener) {
92+
if (unlikely(!atomic_inc_not_zero(&sk_listener->sk_refcnt))) {
93+
kmem_cache_free(ops->slab, req);
94+
return NULL;
9695
}
97-
req_to_sk(req)->sk_prot = sk_listener->sk_prot;
98-
sk_node_init(&req_to_sk(req)->sk_node);
99-
sk_tx_queue_clear(req_to_sk(req));
100-
req->saved_syn = NULL;
101-
/* Following is temporary. It is coupled with debugging
102-
* helpers in reqsk_put() & reqsk_free()
103-
*/
104-
atomic_set(&req->rsk_refcnt, 0);
96+
req->rsk_listener = sk_listener;
10597
}
98+
req->rsk_ops = ops;
99+
req_to_sk(req)->sk_prot = sk_listener->sk_prot;
100+
sk_node_init(&req_to_sk(req)->sk_node);
101+
sk_tx_queue_clear(req_to_sk(req));
102+
req->saved_syn = NULL;
103+
atomic_set(&req->rsk_refcnt, 0);
104+
106105
return req;
107106
}
108107

0 commit comments

Comments
 (0)