syncookies.c 12.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
L
Linus Torvalds 已提交
2 3 4 5
/*
 *  Syncookies implementation for the Linux kernel
 *
 *  Copyright (C) 1997 Andi Kleen
6
 *  Based on ideas by D.J.Bernstein and Eric Schenk.
L
Linus Torvalds 已提交
7 8 9 10 11
 */

#include <linux/tcp.h>
#include <linux/slab.h>
#include <linux/random.h>
12
#include <linux/siphash.h>
L
Linus Torvalds 已提交
13
#include <linux/kernel.h>
14
#include <linux/export.h>
15
#include <net/secure_seq.h>
L
Linus Torvalds 已提交
16
#include <net/tcp.h>
17
#include <net/route.h>
L
Linus Torvalds 已提交
18

19
static siphash_key_t syncookie_secret[2] __read_mostly;
L
Linus Torvalds 已提交
20 21 22 23

#define COOKIEBITS 24	/* Upper bits store count */
#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/* TCP Timestamp: 6 lowest bits of timestamp sent in the cookie SYN-ACK
 * stores TCP options:
 *
 * MSB                               LSB
 * | 31 ...   6 |  5  |  4   | 3 2 1 0 |
 * |  Timestamp | ECN | SACK | WScale  |
 *
 * When we receive a valid cookie-ACK, we look at the echoed tsval (if
 * any) to figure out which TCP options we should use for the rebuilt
 * connection.
 *
 * A WScale setting of '0xf' (which is an invalid scaling value)
 * means that original syn did not include the TCP window scaling option.
 */
#define TS_OPT_WSCALE_MASK	0xf
#define TS_OPT_SACK		BIT(4)
#define TS_OPT_ECN		BIT(5)
/* There is no TS_OPT_TIMESTAMP:
 * if ACK contains timestamp option, we already know it was
 * requested/supported by the syn/synack exchange.
 */
#define TSBITS	6
#define TSMASK	(((__u32)1 << TSBITS) - 1)

48
static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
L
Linus Torvalds 已提交
49 50
		       u32 count, int c)
{
51
	net_get_random_once(syncookie_secret, sizeof(syncookie_secret));
52 53 54
	return siphash_4u32((__force u32)saddr, (__force u32)daddr,
			    (__force u32)sport << 16 | (__force u32)dport,
			    count, &syncookie_secret[c]);
L
Linus Torvalds 已提交
55 56
}

57 58 59

/*
 * when syncookies are in effect and tcp timestamps are enabled we encode
60
 * tcp options in the lower bits of the timestamp value that will be
61 62 63 64
 * sent in the syn-ack.
 * Since subsequent timestamps use the normal tcp_time_stamp value, we
 * must make sure that the resulting initial timestamp is <= tcp_time_stamp.
 */
65
u64 cookie_init_timestamp(struct request_sock *req, u64 now)
66 67
{
	struct inet_request_sock *ireq;
68
	u32 ts, ts_now = tcp_ns_to_ts(now);
69 70 71
	u32 options = 0;

	ireq = inet_rsk(req);
72

73 74 75 76 77
	options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK;
	if (ireq->sack_ok)
		options |= TS_OPT_SACK;
	if (ireq->ecn_ok)
		options |= TS_OPT_ECN;
78 79 80 81 82 83 84 85 86

	ts = ts_now & ~TSMASK;
	ts |= options;
	if (ts > ts_now) {
		ts >>= TSBITS;
		ts--;
		ts <<= TSBITS;
		ts |= options;
	}
87
	return (u64)ts * (NSEC_PER_SEC / TCP_TS_HZ);
88 89 90
}


91
static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
92
				   __be16 dport, __u32 sseq, __u32 data)
L
Linus Torvalds 已提交
93 94 95 96
{
	/*
	 * Compute the secure sequence number.
	 * The output should be:
97
	 *   HASH(sec1,saddr,sport,daddr,dport,sec1) + sseq + (count * 2^24)
L
Linus Torvalds 已提交
98 99 100 101 102 103
	 *      + (HASH(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).
	 * Where sseq is their sequence number and count increases every
	 * minute by 1.
	 * As an extra hack, we add a small "data" value that encodes the
	 * MSS into the second hash value.
	 */
104
	u32 count = tcp_cookie_time();
L
Linus Torvalds 已提交
105 106 107 108 109 110 111 112 113 114 115
	return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
		sseq + (count << COOKIEBITS) +
		((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
		 & COOKIEMASK));
}

/*
 * This retrieves the small "data" value from the syncookie.
 * If the syncookie is bad, the data returned will be out of
 * range.  This must be checked by the caller.
 *
116 117 118
 * The count value used to generate the cookie must be less than
 * MAX_SYNCOOKIE_AGE minutes in the past.
 * The return value (__u32)-1 if this test fails.
L
Linus Torvalds 已提交
119
 */
120
static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
121
				  __be16 sport, __be16 dport, __u32 sseq)
L
Linus Torvalds 已提交
122
{
123
	u32 diff, count = tcp_cookie_time();
L
Linus Torvalds 已提交
124 125 126 127 128

	/* Strip away the layers from the cookie */
	cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;

	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
129
	diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS);
130
	if (diff >= MAX_SYNCOOKIE_AGE)
L
Linus Torvalds 已提交
131 132 133 134 135 136 137
		return (__u32)-1;

	return (cookie -
		cookie_hash(saddr, daddr, sport, dport, count - diff, 1))
		& COOKIEMASK;	/* Leaving the data behind */
}

138
/*
139 140 141 142 143 144 145
 * MSS Values are chosen based on the 2011 paper
 * 'An Analysis of TCP Maximum Segement Sizes' by S. Alcock and R. Nelson.
 * Values ..
 *  .. lower than 536 are rare (< 0.2%)
 *  .. between 537 and 1299 account for less than < 1.5% of observed values
 *  .. in the 1300-1349 range account for about 15 to 20% of observed mss values
 *  .. exceeding 1460 are very rare (< 0.04%)
F
Florian Westphal 已提交
146
 *
147 148
 *  1460 is the single most frequently announced mss value (30 to 46% depending
 *  on monitor location).  Table must be sorted.
L
Linus Torvalds 已提交
149 150
 */
static __u16 const msstab[] = {
F
Florian Westphal 已提交
151
	536,
152 153
	1300,
	1440,	/* 1440, 1452: PPPoE */
F
Florian Westphal 已提交
154
	1460,
L
Linus Torvalds 已提交
155 156 157 158 159 160
};

/*
 * Generate a syncookie.  mssp points to the mss, which is returned
 * rounded down to the value encoded in the cookie.
 */
161 162
u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th,
			      u16 *mssp)
L
Linus Torvalds 已提交
163 164 165 166
{
	int mssind;
	const __u16 mss = *mssp;

F
Florian Westphal 已提交
167 168 169 170
	for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--)
		if (mss >= msstab[mssind])
			break;
	*mssp = msstab[mssind];
L
Linus Torvalds 已提交
171

172 173
	return secure_tcp_syn_cookie(iph->saddr, iph->daddr,
				     th->source, th->dest, ntohl(th->seq),
174
				     mssind);
L
Linus Torvalds 已提交
175
}
176 177
EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence);

178
__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp)
179 180 181 182 183 184
{
	const struct iphdr *iph = ip_hdr(skb);
	const struct tcphdr *th = tcp_hdr(skb);

	return __cookie_v4_init_sequence(iph, th, mssp);
}
L
Linus Torvalds 已提交
185

186 187
/*
 * Check if a ack sequence number is a valid syncookie.
L
Linus Torvalds 已提交
188 189
 * Return the decoded mss if it is, or 0 if not.
 */
190 191
int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
		      u32 cookie)
L
Linus Torvalds 已提交
192
{
193 194
	__u32 seq = ntohl(th->seq) - 1;
	__u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
195
					    th->source, th->dest, seq);
L
Linus Torvalds 已提交
196

F
Florian Westphal 已提交
197
	return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
L
Linus Torvalds 已提交
198
}
199
EXPORT_SYMBOL_GPL(__cookie_v4_check);
L
Linus Torvalds 已提交
200

201 202
struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
				 struct request_sock *req,
203
				 struct dst_entry *dst, u32 tsoff)
L
Linus Torvalds 已提交
204
{
205
	struct inet_connection_sock *icsk = inet_csk(sk);
L
Linus Torvalds 已提交
206
	struct sock *child;
207
	bool own_req;
L
Linus Torvalds 已提交
208

209 210
	child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
						 NULL, &own_req);
211
	if (child) {
212
		refcount_set(&req->rsk_refcnt, 1);
213
		tcp_sk(child)->tsoffset = tsoff;
E
Eric Dumazet 已提交
214
		sock_rps_save_rxhash(child, skb);
215

216
		if (rsk_drop_req(req)) {
217 218 219 220
			refcount_set(&req->rsk_refcnt, 2);
			return child;
		}

221 222 223 224 225
		if (inet_csk_reqsk_queue_add(sk, req, child))
			return child;

		bh_unlock_sock(child);
		sock_put(child);
226
	}
227 228 229
	__reqsk_free(req);

	return NULL;
L
Linus Torvalds 已提交
230
}
231
EXPORT_SYMBOL(tcp_get_cookie_sock);
232 233 234 235 236 237

/*
 * when syncookies are in effect and tcp timestamps are enabled we stored
 * additional tcp options in the timestamp.
 * This extracts these options from the timestamp echo.
 *
238 239
 * return false if we decode a tcp option that is disabled
 * on the host.
240
 */
E
Eric Dumazet 已提交
241 242
bool cookie_timestamp_decode(const struct net *net,
			     struct tcp_options_received *tcp_opt)
243
{
244
	/* echoed timestamp, lowest bits contain options */
245
	u32 options = tcp_opt->rcv_tsecr;
246

247 248 249 250 251
	if (!tcp_opt->saw_tstamp)  {
		tcp_clear_options(tcp_opt);
		return true;
	}

252
	if (!net->ipv4.sysctl_tcp_timestamps)
253 254
		return false;

255
	tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0;
256

E
Eric Dumazet 已提交
257
	if (tcp_opt->sack_ok && !net->ipv4.sysctl_tcp_sack)
258
		return false;
259

260
	if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK)
261 262 263
		return true; /* no window scaling */

	tcp_opt->wscale_ok = 1;
264 265
	tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK;

266
	return net->ipv4.sysctl_tcp_window_scaling != 0;
267
}
268 269 270
EXPORT_SYMBOL(cookie_timestamp_decode);

bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt,
271
		   const struct net *net, const struct dst_entry *dst)
272 273 274 275 276 277 278 279 280
{
	bool ecn_ok = tcp_opt->rcv_tsecr & TS_OPT_ECN;

	if (!ecn_ok)
		return false;

	if (net->ipv4.sysctl_tcp_ecn)
		return true;

281
	return dst_feature(dst, RTAX_FEATURE_ECN);
282 283
}
EXPORT_SYMBOL(cookie_ecn_ok);
284

285 286 287 288
struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
					    struct sock *sk,
					    struct sk_buff *skb)
{
289
	struct tcp_request_sock *treq;
290 291 292 293 294 295 296 297 298 299 300 301
	struct request_sock *req;

#ifdef CONFIG_MPTCP
	if (sk_is_mptcp(sk))
		ops = &mptcp_subflow_request_sock_ops;
#endif

	req = inet_reqsk_alloc(ops, sk, false);
	if (!req)
		return NULL;

	treq = tcp_rsk(req);
302 303
	treq->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
#if IS_ENABLED(CONFIG_MPTCP)
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
	treq->is_mptcp = sk_is_mptcp(sk);
	if (treq->is_mptcp) {
		int err = mptcp_subflow_init_cookie_req(req, sk, skb);

		if (err) {
			reqsk_free(req);
			return NULL;
		}
	}
#endif

	return req;
}
EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc);

319 320 321 322
/* On input, sk is a listener.
 * Output is listener if incoming packet would not create a child
 *           NULL if memory could not be allocated.
 */
C
Cong Wang 已提交
323
struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
L
Linus Torvalds 已提交
324
{
C
Cong Wang 已提交
325
	struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
326
	struct tcp_options_received tcp_opt;
327 328
	struct inet_request_sock *ireq;
	struct tcp_request_sock *treq;
L
Linus Torvalds 已提交
329
	struct tcp_sock *tp = tcp_sk(sk);
330 331
	const struct tcphdr *th = tcp_hdr(skb);
	__u32 cookie = ntohl(th->ack_seq) - 1;
L
Linus Torvalds 已提交
332
	struct sock *ret = sk;
333 334 335
	struct request_sock *req;
	int mss;
	struct rtable *rt;
L
Linus Torvalds 已提交
336
	__u8 rcv_wscale;
E
Eric Dumazet 已提交
337
	struct flowi4 fl4;
338
	u32 tsoff = 0;
L
Linus Torvalds 已提交
339

340
	if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
L
Linus Torvalds 已提交
341 342
		goto out;

343 344 345 346 347
	if (tcp_synq_no_recent_overflow(sk))
		goto out;

	mss = __cookie_v4_check(ip_hdr(skb), th, cookie);
	if (mss == 0) {
348
		__NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
L
Linus Torvalds 已提交
349 350 351
		goto out;
	}

352
	__NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
L
Linus Torvalds 已提交
353

354 355
	/* check for timestamp cookie support */
	memset(&tcp_opt, 0, sizeof(tcp_opt));
356
	tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL);
357

358
	if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) {
359 360 361
		tsoff = secure_tcp_ts_off(sock_net(sk),
					  ip_hdr(skb)->daddr,
					  ip_hdr(skb)->saddr);
362 363 364
		tcp_opt.rcv_tsecr -= tsoff;
	}

E
Eric Dumazet 已提交
365
	if (!cookie_timestamp_decode(sock_net(sk), &tcp_opt))
366
		goto out;
367

L
Linus Torvalds 已提交
368
	ret = NULL;
369
	req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops, sk, skb);
L
Linus Torvalds 已提交
370 371 372
	if (!req)
		goto out;

373 374
	ireq = inet_rsk(req);
	treq = tcp_rsk(req);
375
	treq->rcv_isn		= ntohl(th->seq) - 1;
376
	treq->snt_isn		= cookie;
377
	treq->ts_off		= 0;
378
	treq->txhash		= net_tx_rndhash();
L
Linus Torvalds 已提交
379
	req->mss		= mss;
E
Eric Dumazet 已提交
380 381
	ireq->ir_num		= ntohs(th->dest);
	ireq->ir_rmt_port	= th->source;
382 383
	sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
	sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
384
	ireq->ir_mark		= inet_request_mark(sk, skb);
385 386 387 388 389
	ireq->snd_wscale	= tcp_opt.snd_wscale;
	ireq->sack_ok		= tcp_opt.sack_ok;
	ireq->wscale_ok		= tcp_opt.wscale_ok;
	ireq->tstamp_ok		= tcp_opt.saw_tstamp;
	req->ts_recent		= tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
390
	treq->snt_synack	= 0;
391
	treq->tfo_listener	= false;
392

393 394
	if (IS_ENABLED(CONFIG_SMC))
		ireq->smc_ok = 0;
L
Linus Torvalds 已提交
395

396
	ireq->ir_iif = inet_request_bound_dev_if(sk, skb);
397

L
Linus Torvalds 已提交
398 399 400
	/* We throwed the options of the initial SYN away, so we hope
	 * the ACK carries the same options again (see RFC1122 4.2.3.8)
	 */
E
Eric Dumazet 已提交
401
	RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb));
L
Linus Torvalds 已提交
402

403
	if (security_inet_conn_request(sk, skb, req)) {
404
		reqsk_free(req);
405 406 407
		goto out;
	}

408
	req->num_retrans = 0;
409

L
Linus Torvalds 已提交
410 411 412 413
	/*
	 * We need to lookup the route here to get at the correct
	 * window size. We should better make sure that the window size
	 * hasn't changed since we received the original syn, but I see
414
	 * no easy way to do this.
L
Linus Torvalds 已提交
415
	 */
416
	flowi4_init_output(&fl4, ireq->ir_iif, ireq->ir_mark,
417
			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
E
Eric Dumazet 已提交
418
			   inet_sk_flowi_flags(sk),
C
Cong Wang 已提交
419
			   opt->srr ? opt->faddr : ireq->ir_rmt_addr,
420
			   ireq->ir_loc_addr, th->source, th->dest, sk->sk_uid);
E
Eric Dumazet 已提交
421 422 423
	security_req_classify_flow(req, flowi4_to_flowi(&fl4));
	rt = ip_route_output_key(sock_net(sk), &fl4);
	if (IS_ERR(rt)) {
424
		reqsk_free(req);
E
Eric Dumazet 已提交
425
		goto out;
L
Linus Torvalds 已提交
426 427 428
	}

	/* Try to redo what tcp_v4_send_synack did. */
429
	req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
430

431
	tcp_select_initial_window(sk, tcp_full_space(sk), req->mss,
432
				  &req->rsk_rcv_wnd, &req->rsk_window_clamp,
433
				  ireq->wscale_ok, &rcv_wscale,
434
				  dst_metric(&rt->dst, RTAX_INITRWND));
435

436
	ireq->rcv_wscale  = rcv_wscale;
437
	ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst);
L
Linus Torvalds 已提交
438

439
	ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff);
E
Eric Dumazet 已提交
440 441 442 443 444
	/* ip_queue_xmit() depends on our flow being setup
	 * Normal sockets get it right from inet_csk_route_child_sock()
	 */
	if (ret)
		inet_sk(ret)->cork.fl.u.ip4 = fl4;
L
Linus Torvalds 已提交
445 446
out:	return ret;
}