Tue Jul 7 11:56:57 2020 UTC ()
Pull up following revision(s) (requested by christos in ticket #1566):

	sys/netinet/tcp_input.c: revision 1.418 (via patch)

- always set both ip and ip6, otherwise a kernel assertion can be triggered
- move alignment early so that we do less work


(martin)
diff -r1.357.4.3 -r1.357.4.4 src/sys/netinet/tcp_input.c

cvs diff -r1.357.4.3 -r1.357.4.4 src/sys/netinet/tcp_input.c (expand / switch to unified diff)

--- src/sys/netinet/tcp_input.c 2018/03/30 11:17:19 1.357.4.3
+++ src/sys/netinet/tcp_input.c 2020/07/07 11:56:57 1.357.4.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tcp_input.c,v 1.357.4.3 2018/03/30 11:17:19 martin Exp $ */ 1/* $NetBSD: tcp_input.c,v 1.357.4.4 2020/07/07 11:56:57 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -138,27 +138,27 @@ @@ -138,27 +138,27 @@
138 */ 138 */
139 139
140/* 140/*
141 * TODO list for SYN cache stuff: 141 * TODO list for SYN cache stuff:
142 * 142 *
143 * Find room for a "state" field, which is needed to keep a 143 * Find room for a "state" field, which is needed to keep a
144 * compressed state for TIME_WAIT TCBs. It's been noted already 144 * compressed state for TIME_WAIT TCBs. It's been noted already
145 * that this is fairly important for very high-volume web and 145 * that this is fairly important for very high-volume web and
146 * mail servers, which use a large number of short-lived 146 * mail servers, which use a large number of short-lived
147 * connections. 147 * connections.
148 */ 148 */
149 149
150#include <sys/cdefs.h> 150#include <sys/cdefs.h>
151__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.357.4.3 2018/03/30 11:17:19 martin Exp $"); 151__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.357.4.4 2020/07/07 11:56:57 martin Exp $");
152 152
153#ifdef _KERNEL_OPT 153#ifdef _KERNEL_OPT
154#include "opt_inet.h" 154#include "opt_inet.h"
155#include "opt_ipsec.h" 155#include "opt_ipsec.h"
156#include "opt_inet_csum.h" 156#include "opt_inet_csum.h"
157#include "opt_tcp_debug.h" 157#include "opt_tcp_debug.h"
158#endif 158#endif
159 159
160#include <sys/param.h> 160#include <sys/param.h>
161#include <sys/systm.h> 161#include <sys/systm.h>
162#include <sys/malloc.h> 162#include <sys/malloc.h>
163#include <sys/mbuf.h> 163#include <sys/mbuf.h>
164#include <sys/protosw.h> 164#include <sys/protosw.h>
@@ -1263,56 +1263,70 @@ tcp_input(struct mbuf *m, ...) @@ -1263,56 +1263,70 @@ tcp_input(struct mbuf *m, ...)
1263 */ 1263 */
1264 if (m->m_flags & (M_BCAST|M_MCAST)) { 1264 if (m->m_flags & (M_BCAST|M_MCAST)) {
1265 /* XXX stat */ 1265 /* XXX stat */
1266 goto drop; 1266 goto drop;
1267 } 1267 }
1268#ifdef INET6 1268#ifdef INET6
1269 if (m->m_flags & M_ANYCAST6) { 1269 if (m->m_flags & M_ANYCAST6) {
1270 /* XXX stat */ 1270 /* XXX stat */
1271 goto drop; 1271 goto drop;
1272 } 1272 }
1273#endif 1273#endif
1274 1274
1275 /* 1275 /*
 1276 * Enforce alignment requirements that are violated in
 1277 * some cases, see kern/50766 for details.
 1278 */
 1279 if (TCP_HDR_ALIGNED_P(th) == 0) {
 1280 m = m_copyup(m, toff + sizeof(struct tcphdr), 0);
 1281 if (m == NULL) {
 1282 TCP_STATINC(TCP_STAT_RCVSHORT);
 1283 return;
 1284 }
 1285 th = (struct tcphdr *)(mtod(m, char *) + toff);
 1286 }
 1287 KASSERT(TCP_HDR_ALIGNED_P(th));
 1288
 1289 /*
1276 * Get IP and TCP header. 1290 * Get IP and TCP header.
1277 * Note: IP leaves IP header in first mbuf. 1291 * Note: IP leaves IP header in first mbuf.
1278 */ 1292 */
 1293#ifdef INET6
 1294 ip6 = mtod(m, struct ip6_hdr *);
 1295#endif
 1296#ifdef INET
1279 ip = mtod(m, struct ip *); 1297 ip = mtod(m, struct ip *);
 1298#endif
1280 switch (ip->ip_v) { 1299 switch (ip->ip_v) {
1281#ifdef INET 1300#ifdef INET
1282 case 4: 1301 case 4:
1283#ifdef INET6 
1284 ip6 = NULL; 
1285#endif 
1286 af = AF_INET; 1302 af = AF_INET;
1287 iphlen = sizeof(struct ip); 1303 iphlen = sizeof(struct ip);
1288 IP6_EXTHDR_GET(th, struct tcphdr *, m, toff, 1304 IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
1289 sizeof(struct tcphdr)); 1305 sizeof(struct tcphdr));
1290 if (th == NULL) { 1306 if (th == NULL) {
1291 TCP_STATINC(TCP_STAT_RCVSHORT); 1307 TCP_STATINC(TCP_STAT_RCVSHORT);
1292 return; 1308 return;
1293 } 1309 }
1294 /* We do the checksum after PCB lookup... */ 1310 /* We do the checksum after PCB lookup... */
1295 len = ntohs(ip->ip_len); 1311 len = ntohs(ip->ip_len);
1296 tlen = len - toff; 1312 tlen = len - toff;
1297 iptos = ip->ip_tos; 1313 iptos = ip->ip_tos;
1298 break; 1314 break;
1299#endif 1315#endif
1300#ifdef INET6 1316#ifdef INET6
1301 case 6: 1317 case 6:
1302 ip = NULL; 
1303 iphlen = sizeof(struct ip6_hdr); 1318 iphlen = sizeof(struct ip6_hdr);
1304 af = AF_INET6; 1319 af = AF_INET6;
1305 ip6 = mtod(m, struct ip6_hdr *); 
1306 IP6_EXTHDR_GET(th, struct tcphdr *, m, toff, 1320 IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
1307 sizeof(struct tcphdr)); 1321 sizeof(struct tcphdr));
1308 if (th == NULL) { 1322 if (th == NULL) {
1309 TCP_STATINC(TCP_STAT_RCVSHORT); 1323 TCP_STATINC(TCP_STAT_RCVSHORT);
1310 return; 1324 return;
1311 } 1325 }
1312 1326
1313 /* Be proactive about malicious use of IPv4 mapped address */ 1327 /* Be proactive about malicious use of IPv4 mapped address */
1314 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 1328 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
1315 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 1329 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
1316 /* XXX stat */ 1330 /* XXX stat */
1317 goto drop; 1331 goto drop;
1318 } 1332 }
@@ -1339,43 +1353,26 @@ tcp_input(struct mbuf *m, ...) @@ -1339,43 +1353,26 @@ tcp_input(struct mbuf *m, ...)
1339 goto drop; 1353 goto drop;
1340 } 1354 }
1341 1355
1342 /* We do the checksum after PCB lookup... */ 1356 /* We do the checksum after PCB lookup... */
1343 len = m->m_pkthdr.len; 1357 len = m->m_pkthdr.len;
1344 tlen = len - toff; 1358 tlen = len - toff;
1345 iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 1359 iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
1346 break; 1360 break;
1347#endif 1361#endif
1348 default: 1362 default:
1349 m_freem(m); 1363 m_freem(m);
1350 return; 1364 return;
1351 } 1365 }
1352 /* 
1353 * Enforce alignment requirements that are violated in 
1354 * some cases, see kern/50766 for details. 
1355 */ 
1356 if (TCP_HDR_ALIGNED_P(th) == 0) { 
1357 m = m_copyup(m, toff + sizeof(struct tcphdr), 0); 
1358 if (m == NULL) { 
1359 TCP_STATINC(TCP_STAT_RCVSHORT); 
1360 return; 
1361 } 
1362 ip = mtod(m, struct ip *); 
1363#ifdef INET6 
1364 ip6 = mtod(m, struct ip6_hdr *); 
1365#endif 
1366 th = (struct tcphdr *)(mtod(m, char *) + toff); 
1367 } 
1368 KASSERT(TCP_HDR_ALIGNED_P(th)); 
1369 1366
1370 /* 1367 /*
1371 * Check that TCP offset makes sense, 1368 * Check that TCP offset makes sense,
1372 * pull out TCP options and adjust length. XXX 1369 * pull out TCP options and adjust length. XXX
1373 */ 1370 */
1374 off = th->th_off << 2; 1371 off = th->th_off << 2;
1375 if (off < sizeof (struct tcphdr) || off > tlen) { 1372 if (off < sizeof (struct tcphdr) || off > tlen) {
1376 TCP_STATINC(TCP_STAT_RCVBADOFF); 1373 TCP_STATINC(TCP_STAT_RCVBADOFF);
1377 goto drop; 1374 goto drop;
1378 } 1375 }
1379 tlen -= off; 1376 tlen -= off;
1380 1377
1381 /* 1378 /*
@@ -1591,27 +1588,26 @@ findpcb: @@ -1591,27 +1588,26 @@ findpcb:
1591 /* Unscale the window into a 32-bit value. */ 1588 /* Unscale the window into a 32-bit value. */
1592 if ((tiflags & TH_SYN) == 0) 1589 if ((tiflags & TH_SYN) == 0)
1593 tiwin = th->th_win << tp->snd_scale; 1590 tiwin = th->th_win << tp->snd_scale;
1594 else 1591 else
1595 tiwin = th->th_win; 1592 tiwin = th->th_win;
1596 1593
1597#ifdef INET6 1594#ifdef INET6
1598 /* save packet options if user wanted */ 1595 /* save packet options if user wanted */
1599 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS)) { 1596 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS)) {
1600 if (in6p->in6p_options) { 1597 if (in6p->in6p_options) {
1601 m_freem(in6p->in6p_options); 1598 m_freem(in6p->in6p_options);
1602 in6p->in6p_options = 0; 1599 in6p->in6p_options = 0;
1603 } 1600 }
1604 KASSERT(ip6 != NULL); 
1605 ip6_savecontrol(in6p, &in6p->in6p_options, ip6, m); 1601 ip6_savecontrol(in6p, &in6p->in6p_options, ip6, m);
1606 } 1602 }
1607#endif 1603#endif
1608 1604
1609 if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) { 1605 if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
1610 union syn_cache_sa src; 1606 union syn_cache_sa src;
1611 union syn_cache_sa dst; 1607 union syn_cache_sa dst;
1612 1608
1613 memset(&src, 0, sizeof(src)); 1609 memset(&src, 0, sizeof(src));
1614 memset(&dst, 0, sizeof(dst)); 1610 memset(&dst, 0, sizeof(dst));
1615 switch (af) { 1611 switch (af) {
1616#ifdef INET 1612#ifdef INET
1617 case AF_INET: 1613 case AF_INET: