Author: tuexen
Date: Wed Jul  1 21:52:14 2020
New Revision: 362872
URL: https://svnweb.freebsd.org/changeset/base/362872

Log:
  MFC r356270:
  Improve input validation of the spp_pathmtu field in the
  SCTP_PEER_ADDR_PARAMS socket option. The code in the stack assumes
  sane values for the MTU.
  
  This issue was found by running an instance of syzkaller.
  
  MFC r356271:
  Remove empty line which was added in previous commit by accident.

Modified:
  stable/12/sys/netinet/sctp.h
  stable/12/sys/netinet/sctp_usrreq.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/sctp.h
==============================================================================
--- stable/12/sys/netinet/sctp.h        Wed Jul  1 21:48:17 2020        
(r362871)
+++ stable/12/sys/netinet/sctp.h        Wed Jul  1 21:52:14 2020        
(r362872)
@@ -585,8 +585,10 @@ struct sctp_error_auth_invalid_hmac {
 #define SCTP_MOBILITY_PRIM_DELETED       0x00000004
 
 
-#define SCTP_SMALLEST_PMTU 512 /* smallest pmtu allowed when disabling PMTU
-                                * discovery */
+/* Smallest PMTU allowed when disabling PMTU discovery */
+#define SCTP_SMALLEST_PMTU 512
+/* Largest PMTU allowed when disabling PMTU discovery */
+#define SCTP_LARGEST_PMTU  65536
 
 #undef SCTP_PACKED
 

Modified: stable/12/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/12/sys/netinet/sctp_usrreq.c Wed Jul  1 21:48:17 2020        
(r362871)
+++ stable/12/sys/netinet/sctp_usrreq.c Wed Jul  1 21:52:14 2020        
(r362872)
@@ -5363,6 +5363,14 @@ sctp_setopt(struct socket *so, int optname, void *optv
                                SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EINVAL);
                                return (EINVAL);
                        }
+                       if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) &&
+                           ((paddrp->spp_pathmtu < SCTP_SMALLEST_PMTU) ||
+                           (paddrp->spp_pathmtu > SCTP_LARGEST_PMTU))) {
+                               if (stcb)
+                                       SCTP_TCB_UNLOCK(stcb);
+                               SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EINVAL);
+                               return (EINVAL);
+                       }
 
                        if (stcb != NULL) {
                                /************************TCB SPECIFIC SET 
******************/
@@ -5394,7 +5402,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
                                                        
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
                                                }
                                        }
-                                       if ((paddrp->spp_flags & 
SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
+                                       if (paddrp->spp_flags & 
SPP_PMTUD_DISABLE) {
                                                if 
(SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
                                                        
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
                                                            
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
@@ -5536,7 +5544,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
                                                }
                                                sctp_stcb_feature_on(inp, stcb, 
SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
                                        }
-                                       if ((paddrp->spp_flags & 
SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
+                                       if (paddrp->spp_flags & 
SPP_PMTUD_DISABLE) {
                                                TAILQ_FOREACH(net, 
&stcb->asoc.nets, sctp_next) {
                                                        if 
(SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
                                                                
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
@@ -5635,9 +5643,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
                                                inp->sctp_ep.default_mtu = 0;
                                                sctp_feature_off(inp, 
SCTP_PCB_FLAGS_DO_NOT_PMTUD);
                                        } else if (paddrp->spp_flags & 
SPP_PMTUD_DISABLE) {
-                                               if (paddrp->spp_pathmtu >= 
SCTP_SMALLEST_PMTU) {
-                                                       
inp->sctp_ep.default_mtu = paddrp->spp_pathmtu;
-                                               }
+                                               inp->sctp_ep.default_mtu = 
paddrp->spp_pathmtu;
                                                sctp_feature_on(inp, 
SCTP_PCB_FLAGS_DO_NOT_PMTUD);
                                        }
                                        if (paddrp->spp_flags & SPP_DSCP) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to