Author: tuexen
Date: Sat Mar 23 22:56:03 2019
New Revision: 345461
URL: https://svnweb.freebsd.org/changeset/base/345461

Log:
  Limit the size of messages sent on 1-to-many style SCTP sockets with the
  SCTP_SENDALL flag. Allow also only one operation per SCTP endpoint.
  
  This fixes an issue found by running syzkaller and is joint work with rrs@.
  
  MFC after:            1 week

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_output.c

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h     Sat Mar 23 22:46:29 2019        (r345460)
+++ head/sys/netinet/sctp.h     Sat Mar 23 22:56:03 2019        (r345461)
@@ -491,6 +491,7 @@ struct sctp_error_auth_invalid_hmac {
                                         * time */
 #define SCTP_SAT_NETWORK_BURST_INCR  2 /* how many times to multiply maxburst
                                         * in sat */
+#define SCTP_MAX_SENDALL_LIMIT 1024
 
 /* Data Chuck Specific Flags */
 #define SCTP_DATA_FRAG_MASK        0x03
@@ -516,6 +517,7 @@ struct sctp_error_auth_invalid_hmac {
 #define SCTP_PCB_FLAGS_BOUNDALL                0x00000004
 #define SCTP_PCB_FLAGS_ACCEPTING       0x00000008
 #define SCTP_PCB_FLAGS_UNBOUND         0x00000010
+#define SCTP_PCB_FLAGS_SND_ITERATOR_UP  0x00000020
 #define SCTP_PCB_FLAGS_CLOSE_IP         0x00040000
 #define SCTP_PCB_FLAGS_WAS_CONNECTED    0x00080000
 #define SCTP_PCB_FLAGS_WAS_ABORTED      0x00100000

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c      Sat Mar 23 22:46:29 2019        
(r345460)
+++ head/sys/netinet/sctp_output.c      Sat Mar 23 22:56:03 2019        
(r345461)
@@ -6804,6 +6804,10 @@ sctp_sendall_completes(void *ptr, uint32_t val SCTP_UN
         */
 
        /* now free everything */
+       if (ca->inp) {
+               /* Lets clear the flag to allow others to run. */
+               ca->inp->sctp_flags &= ~SCTP_PCB_FLAGS_SND_ITERATOR_UP;
+       }
        sctp_m_freem(ca->m);
        SCTP_FREE(ca, SCTP_M_COPYAL);
 }
@@ -6857,6 +6861,14 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, 
        int ret;
        struct sctp_copy_all *ca;
 
+       if (inp->sctp_flags & SCTP_PCB_FLAGS_SND_ITERATOR_UP) {
+               /* There is another. */
+               return (EBUSY);
+       }
+       if (uio->uio_resid > SCTP_MAX_SENDALL_LIMIT) {
+               /* You must be less than the max! */
+               return (EMSGSIZE);
+       }
        SCTP_MALLOC(ca, struct sctp_copy_all *, sizeof(struct sctp_copy_all),
            SCTP_M_COPYAL);
        if (ca == NULL) {
@@ -6893,6 +6905,7 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, 
                        ca->sndlen += SCTP_BUF_LEN(mat);
                }
        }
+       inp->sctp_flags |= SCTP_PCB_FLAGS_SND_ITERATOR_UP;
        ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
            SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
            SCTP_ASOC_ANY_STATE,
_______________________________________________
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