aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/syncookies.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2015-03-17 21:32:31 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-17 22:02:29 -0400
commit0470c8ca1d57927f2cc3e1d5add1fb2834609447 (patch)
tree798f475f48fbdff0eae359c3f345a1a0eaf83ca2 /net/ipv4/syncookies.c
parente3d95ad7da4f8955599f0786d7c70497c0aaf8c9 (diff)
inet: fix request sock refcounting
While testing last patch series, I found req sock refcounting was wrong. We must set skc_refcnt to 1 for all request socks added in hashes, but also on request sockets created by FastOpen or syncookies. It is tricky because we need to defer this initialization so that future RCU lookups do not try to take a refcount on a not yet fully initialized request socket. Also get rid of ireq_refcnt alias. Signed-off-by: Eric Dumazet <edumazet@google.com> Fixes: 13854e5a6046 ("inet: add proper refcounting to request sock") Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/syncookies.c')
-rw-r--r--net/ipv4/syncookies.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 574b67765a06..34e755403715 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -227,11 +227,12 @@ static struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
227 struct sock *child; 227 struct sock *child;
228 228
229 child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst); 229 child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
230 if (child) 230 if (child) {
231 atomic_set(&req->rsk_refcnt, 1);
231 inet_csk_reqsk_queue_add(sk, req, child); 232 inet_csk_reqsk_queue_add(sk, req, child);
232 else 233 } else {
233 reqsk_free(req); 234 reqsk_free(req);
234 235 }
235 return child; 236 return child;
236} 237}
237 238
@@ -356,7 +357,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
356 ireq->opt = tcp_v4_save_options(skb); 357 ireq->opt = tcp_v4_save_options(skb);
357 358
358 if (security_inet_conn_request(sk, skb, req)) { 359 if (security_inet_conn_request(sk, skb, req)) {
359 reqsk_put(req); 360 reqsk_free(req);
360 goto out; 361 goto out;
361 } 362 }
362 363
@@ -377,7 +378,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
377 security_req_classify_flow(req, flowi4_to_flowi(&fl4)); 378 security_req_classify_flow(req, flowi4_to_flowi(&fl4));
378 rt = ip_route_output_key(sock_net(sk), &fl4); 379 rt = ip_route_output_key(sock_net(sk), &fl4);
379 if (IS_ERR(rt)) { 380 if (IS_ERR(rt)) {
380 reqsk_put(req); 381 reqsk_free(req);
381 goto out; 382 goto out;
382 } 383 }
383 384