hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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,44 @@
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
+ if (sk_is_mptcp(sk))
294
+ req = mptcp_subflow_reqsk_alloc(ops, sk, false);
295
+ else
296
+ req = inet_reqsk_alloc(ops, sk, false);
297
+
298
+ if (!req)
299
+ return NULL;
300
+
301
+ treq = tcp_rsk(req);
302
+
303
+ /* treq->af_specific might be used to perform TCP_MD5 lookup */
304
+ treq->af_specific = af_ops;
305
+
306
+ treq->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
307
+#if IS_ENABLED(CONFIG_MPTCP)
308
+ treq->is_mptcp = sk_is_mptcp(sk);
309
+ if (treq->is_mptcp) {
310
+ int err = mptcp_subflow_init_cookie_req(req, sk, skb);
311
+
312
+ if (err) {
313
+ reqsk_free(req);
314
+ return NULL;
315
+ }
316
+ }
317
+#endif
318
+
319
+ return req;
320
+}
321
+EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc);
283322
284323 /* On input, sk is a listener.
285324 * Output is listener if incoming packet would not create a child
....@@ -302,7 +341,8 @@
302341 struct flowi4 fl4;
303342 u32 tsoff = 0;
304343
305
- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
344
+ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
345
+ !th->ack || th->rst)
306346 goto out;
307347
308348 if (tcp_synq_no_recent_overflow(sk))
....@@ -331,7 +371,8 @@
331371 goto out;
332372
333373 ret = NULL;
334
- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */
374
+ req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops,
375
+ &tcp_request_sock_ipv4_ops, sk, skb);
335376 if (!req)
336377 goto out;
337378
....@@ -354,6 +395,7 @@
354395 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
355396 treq->snt_synack = 0;
356397 treq->tfo_listener = false;
398
+
357399 if (IS_ENABLED(CONFIG_SMC))
358400 ireq->smc_ok = 0;
359401
....@@ -382,7 +424,7 @@
382424 inet_sk_flowi_flags(sk),
383425 opt->srr ? opt->faddr : ireq->ir_rmt_addr,
384426 ireq->ir_loc_addr, th->source, th->dest, sk->sk_uid);
385
- security_req_classify_flow(req, flowi4_to_flowi(&fl4));
427
+ security_req_classify_flow(req, flowi4_to_flowi_common(&fl4));
386428 rt = ip_route_output_key(sock_net(sk), &fl4);
387429 if (IS_ERR(rt)) {
388430 reqsk_free(req);