hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/net/ipv4/syncookies.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Syncookies implementation for the Linux kernel
34 *
45 * Copyright (C) 1997 Andi Kleen
56 * Based on ideas by D.J.Bernstein and Eric Schenk.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
117 */
128
139 #include <linux/tcp.h>
....@@ -66,10 +62,10 @@
6662 * Since subsequent timestamps use the normal tcp_time_stamp value, we
6763 * must make sure that the resulting initial timestamp is <= tcp_time_stamp.
6864 */
69
-u64 cookie_init_timestamp(struct request_sock *req)
65
+u64 cookie_init_timestamp(struct request_sock *req, u64 now)
7066 {
7167 struct inet_request_sock *ireq;
72
- u32 ts, ts_now = tcp_time_stamp_raw();
68
+ u32 ts, ts_now = tcp_ns_to_ts(now);
7369 u32 options = 0;
7470
7571 ireq = inet_rsk(req);
....@@ -88,7 +84,7 @@
8884 ts <<= TSBITS;
8985 ts |= options;
9086 }
91
- return (u64)ts * (USEC_PER_SEC / TCP_TS_HZ);
87
+ return (u64)ts * (NSEC_PER_SEC / TCP_TS_HZ);
9288 }
9389
9490
....@@ -216,16 +212,21 @@
216212 refcount_set(&req->rsk_refcnt, 1);
217213 tcp_sk(child)->tsoffset = tsoff;
218214 sock_rps_save_rxhash(child, skb);
219
- if (!inet_csk_reqsk_queue_add(sk, req, child)) {
220
- bh_unlock_sock(child);
221
- sock_put(child);
222
- child = NULL;
215
+
216
+ if (rsk_drop_req(req)) {
223217 reqsk_put(req);
218
+ return child;
224219 }
225
- } else {
226
- reqsk_free(req);
220
+
221
+ if (inet_csk_reqsk_queue_add(sk, req, child))
222
+ return child;
223
+
224
+ bh_unlock_sock(child);
225
+ sock_put(child);
227226 }
228
- return child;
227
+ __reqsk_free(req);
228
+
229
+ return NULL;
229230 }
230231 EXPORT_SYMBOL(tcp_get_cookie_sock);
231232
....@@ -248,12 +249,12 @@
248249 return true;
249250 }
250251
251
- if (!net->ipv4.sysctl_tcp_timestamps)
252
+ if (!READ_ONCE(net->ipv4.sysctl_tcp_timestamps))
252253 return false;
253254
254255 tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0;
255256
256
- if (tcp_opt->sack_ok && !net->ipv4.sysctl_tcp_sack)
257
+ if (tcp_opt->sack_ok && !READ_ONCE(net->ipv4.sysctl_tcp_sack))
257258 return false;
258259
259260 if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK)
....@@ -262,7 +263,7 @@
262263 tcp_opt->wscale_ok = 1;
263264 tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK;
264265
265
- return net->ipv4.sysctl_tcp_window_scaling != 0;
266
+ return READ_ONCE(net->ipv4.sysctl_tcp_window_scaling) != 0;
266267 }
267268 EXPORT_SYMBOL(cookie_timestamp_decode);
268269
....@@ -280,6 +281,45 @@
280281 return dst_feature(dst, RTAX_FEATURE_ECN);
281282 }
282283 EXPORT_SYMBOL(cookie_ecn_ok);
284
+
285
+struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
286
+ const struct tcp_request_sock_ops *af_ops,
287
+ struct sock *sk,
288
+ struct sk_buff *skb)
289
+{
290
+ struct tcp_request_sock *treq;
291
+ struct request_sock *req;
292
+
293
+#ifdef CONFIG_MPTCP
294
+ if (sk_is_mptcp(sk))
295
+ ops = &mptcp_subflow_request_sock_ops;
296
+#endif
297
+
298
+ req = inet_reqsk_alloc(ops, sk, false);
299
+ if (!req)
300
+ return NULL;
301
+
302
+ treq = tcp_rsk(req);
303
+
304
+ /* treq->af_specific might be used to perform TCP_MD5 lookup */
305
+ treq->af_specific = af_ops;
306
+
307
+ treq->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
308
+#if IS_ENABLED(CONFIG_MPTCP)
309
+ treq->is_mptcp = sk_is_mptcp(sk);
310
+ if (treq->is_mptcp) {
311
+ int err = mptcp_subflow_init_cookie_req(req, sk, skb);
312
+
313
+ if (err) {
314
+ reqsk_free(req);
315
+ return NULL;
316
+ }
317
+ }
318
+#endif
319
+
320
+ return req;
321
+}
322
+EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc);
283323
284324 /* On input, sk is a listener.
285325 * Output is listener if incoming packet would not create a child
....@@ -302,7 +342,8 @@
302342 struct flowi4 fl4;
303343 u32 tsoff = 0;
304344
305
- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
345
+ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
346
+ !th->ack || th->rst)
306347 goto out;
307348
308349 if (tcp_synq_no_recent_overflow(sk))
....@@ -331,7 +372,8 @@
331372 goto out;
332373
333374 ret = NULL;
334
- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */
375
+ req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops,
376
+ &tcp_request_sock_ipv4_ops, sk, skb);
335377 if (!req)
336378 goto out;
337379
....@@ -354,6 +396,7 @@
354396 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
355397 treq->snt_synack = 0;
356398 treq->tfo_listener = false;
399
+
357400 if (IS_ENABLED(CONFIG_SMC))
358401 ireq->smc_ok = 0;
359402
....@@ -382,7 +425,7 @@
382425 inet_sk_flowi_flags(sk),
383426 opt->srr ? opt->faddr : ireq->ir_rmt_addr,
384427 ireq->ir_loc_addr, th->source, th->dest, sk->sk_uid);
385
- security_req_classify_flow(req, flowi4_to_flowi(&fl4));
428
+ security_req_classify_flow(req, flowi4_to_flowi_common(&fl4));
386429 rt = ip_route_output_key(sock_net(sk), &fl4);
387430 if (IS_ERR(rt)) {
388431 reqsk_free(req);