Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet Avoid stack overflow when SACK and TCP_SIGNATURE...
details: https://anonhg.NetBSD.org/src/rev/3491ea3019e5
branches: trunk
changeset: 333252:3491ea3019e5
user: christos <christos%NetBSD.org@localhost>
date: Sat Oct 25 15:07:13 2014 +0000
description:
Avoid stack overflow when SACK and TCP_SIGNATURE are both present. Thanks
to Jonathan Looney for pointing this out.
diffstat:
sys/netinet/tcp_output.c | 55 ++++++++++++++++++++++++++---------------------
1 files changed, 30 insertions(+), 25 deletions(-)
diffs (116 lines):
diff -r 8645e92f4374 -r 3491ea3019e5 sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c Sat Oct 25 15:02:12 2014 +0000
+++ b/sys/netinet/tcp_output.c Sat Oct 25 15:07:13 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_output.c,v 1.177 2014/10/21 13:44:47 hikaru Exp $ */
+/* $NetBSD: tcp_output.c,v 1.178 2014/10/25 15:07:13 christos Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -135,7 +135,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.177 2014/10/21 13:44:47 hikaru Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.178 2014/10/25 15:07:13 christos Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -557,6 +557,7 @@
#endif
struct tcphdr *th;
u_char opt[MAX_TCPOPTLEN];
+#define OPT_FITS(more) ((optlen + (more)) < sizeof(opt))
unsigned optlen, hdrlen, packetlen;
unsigned int sack_numblks;
int idle, sendalot, txsegsize, rxsegsize;
@@ -1123,7 +1124,7 @@
tp->snd_nxt = tp->iss;
tp->t_ourmss = tcp_mss_to_advertise(synrt != NULL ?
synrt->rt_ifp : NULL, af);
- if ((tp->t_flags & TF_NOOPT) == 0) {
+ if ((tp->t_flags & TF_NOOPT) == 0 && OPT_FITS(4)) {
opt[0] = TCPOPT_MAXSEG;
opt[1] = 4;
opt[2] = (tp->t_ourmss >> 8) & 0xff;
@@ -1132,7 +1133,8 @@
if ((tp->t_flags & TF_REQ_SCALE) &&
((flags & TH_ACK) == 0 ||
- (tp->t_flags & TF_RCVD_SCALE))) {
+ (tp->t_flags & TF_RCVD_SCALE)) &&
+ OPT_FITS(4)) {
*((u_int32_t *) (opt + optlen)) = htonl(
TCPOPT_NOP << 24 |
TCPOPT_WINDOW << 16 |
@@ -1140,7 +1142,7 @@
tp->request_r_scale);
optlen += 4;
}
- if (tcp_do_sack) {
+ if (tcp_do_sack && OPT_FITS(4)) {
u_int8_t *cp = (u_int8_t *)(opt + optlen);
cp[0] = TCPOPT_SACK_PERMITTED;
@@ -1160,7 +1162,7 @@
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(flags & TH_RST) == 0 &&
((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
- (tp->t_flags & TF_RCVD_TSTMP))) {
+ (tp->t_flags & TF_RCVD_TSTMP)) && OPT_FITS(TCPOLEN_TSTAMP_APPA)) {
u_int32_t *lp = (u_int32_t *)(opt + optlen);
/* Form timestamp option as shown in appendix A of RFC 1323. */
@@ -1184,30 +1186,33 @@
struct ipqent *tiqe;
sack_len = sack_numblks * 8 + 2;
- bp[0] = TCPOPT_NOP;
- bp[1] = TCPOPT_NOP;
- bp[2] = TCPOPT_SACK;
- bp[3] = sack_len;
- if ((tp->rcv_sack_flags & TCPSACK_HAVED) != 0) {
- sack_numblks--;
- *lp++ = htonl(tp->rcv_dsack_block.left);
- *lp++ = htonl(tp->rcv_dsack_block.right);
- tp->rcv_sack_flags &= ~TCPSACK_HAVED;
+ if (OPT_FITS(sack_len + 2)) {
+ bp[0] = TCPOPT_NOP;
+ bp[1] = TCPOPT_NOP;
+ bp[2] = TCPOPT_SACK;
+ bp[3] = sack_len;
+ if ((tp->rcv_sack_flags & TCPSACK_HAVED) != 0) {
+ sack_numblks--;
+ *lp++ = htonl(tp->rcv_dsack_block.left);
+ *lp++ = htonl(tp->rcv_dsack_block.right);
+ tp->rcv_sack_flags &= ~TCPSACK_HAVED;
+ }
+ for (tiqe = TAILQ_FIRST(&tp->timeq);
+ sack_numblks > 0;
+ tiqe = TAILQ_NEXT(tiqe, ipqe_timeq)) {
+ KASSERT(tiqe != NULL);
+ sack_numblks--;
+ *lp++ = htonl(tiqe->ipqe_seq);
+ *lp++ = htonl(tiqe->ipqe_seq + tiqe->ipqe_len +
+ ((tiqe->ipqe_flags & TH_FIN) != 0 ? 1 : 0));
+ }
+ optlen += sack_len + 2;
}
- for (tiqe = TAILQ_FIRST(&tp->timeq);
- sack_numblks > 0; tiqe = TAILQ_NEXT(tiqe, ipqe_timeq)) {
- KASSERT(tiqe != NULL);
- sack_numblks--;
- *lp++ = htonl(tiqe->ipqe_seq);
- *lp++ = htonl(tiqe->ipqe_seq + tiqe->ipqe_len +
- ((tiqe->ipqe_flags & TH_FIN) != 0 ? 1 : 0));
- }
- optlen += sack_len + 2;
}
TCP_REASS_UNLOCK(tp);
#ifdef TCP_SIGNATURE
- if (tp->t_flags & TF_SIGNATURE) {
+ if ((tp->t_flags & TF_SIGNATURE) && OPT_FITS(TCPOLEN_SIGNATURE + 2)) {
u_char *bp;
/*
* Initialize TCP-MD5 option (RFC2385)
Home |
Main Index |
Thread Index |
Old Index