tcp: handle inet_csk_reqsk_queue_add() failures
Commit7716682cc5
("tcp/dccp: fix another race at listener dismantle") let inet_csk_reqsk_queue_add() fail, and adjusted {tcp,dccp}_check_req() accordingly. However, TFO and syncookies weren't modified, thus leaking allocated resources on error. Contrary to tcp_check_req(), in both syncookies and TFO cases, we need to drop the request socket. Also, since the child socket is created with inet_csk_clone_lock(), we have to unlock it and drop an extra reference (->sk_refcount is initially set to 2 and inet_csk_reqsk_queue_add() drops only one ref). For TFO, we also need to revert the work done by tcp_try_fastopen() (with reqsk_fastopen_remove()). Fixes:7716682cc5
("tcp/dccp: fix another race at listener dismantle") Signed-off-by: Guillaume Nault <gnault@redhat.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
09073525f8
Коммит
9d3e1368bb
|
@ -216,7 +216,12 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
|
|||
refcount_set(&req->rsk_refcnt, 1);
|
||||
tcp_sk(child)->tsoffset = tsoff;
|
||||
sock_rps_save_rxhash(child, skb);
|
||||
inet_csk_reqsk_queue_add(sk, req, child);
|
||||
if (!inet_csk_reqsk_queue_add(sk, req, child)) {
|
||||
bh_unlock_sock(child);
|
||||
sock_put(child);
|
||||
child = NULL;
|
||||
reqsk_put(req);
|
||||
}
|
||||
} else {
|
||||
reqsk_free(req);
|
||||
}
|
||||
|
|
|
@ -6498,7 +6498,13 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
|||
af_ops->send_synack(fastopen_sk, dst, &fl, req,
|
||||
&foc, TCP_SYNACK_FASTOPEN);
|
||||
/* Add the child socket directly into the accept queue */
|
||||
inet_csk_reqsk_queue_add(sk, req, fastopen_sk);
|
||||
if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) {
|
||||
reqsk_fastopen_remove(fastopen_sk, req, false);
|
||||
bh_unlock_sock(fastopen_sk);
|
||||
sock_put(fastopen_sk);
|
||||
reqsk_put(req);
|
||||
goto drop;
|
||||
}
|
||||
sk->sk_data_ready(sk);
|
||||
bh_unlock_sock(fastopen_sk);
|
||||
sock_put(fastopen_sk);
|
||||
|
|
Загрузка…
Ссылка в новой задаче