Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/sys/netinet Pull up following revision(s) (requested by c...



details:   https://anonhg.NetBSD.org/src/rev/ab882ae854a9
branches:  netbsd-7
changeset: 798463:ab882ae854a9
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Oct 26 09:48:18 2014 +0000

description:
Pull up following revision(s) (requested by christos in ticket #157):
        sys/netinet/tcp_output.c: revision 1.178
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 7240b6985e2a -r ab882ae854a9 sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c  Sat Oct 25 10:02:15 2014 +0000
+++ b/sys/netinet/tcp_output.c  Sun Oct 26 09:48:18 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_output.c,v 1.176.2.1 2014/10/24 07:28:14 martin Exp $      */
+/*     $NetBSD: tcp_output.c,v 1.176.2.2 2014/10/26 09:48:18 martin 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.176.2.1 2014/10/24 07:28:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.176.2.2 2014/10/26 09:48:18 martin 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