From 46b48062555aa5c40ee4b20740e64c7f49b85584 Mon Sep 17 00:00:00 2001 From: tuexen Date: Sat, 23 Mar 2019 22:56:03 +0000 Subject: [PATCH] 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 --- sys/netinet/sctp.h | 2 ++ sys/netinet/sctp_output.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/sys/netinet/sctp.h b/sys/netinet/sctp.h index 64fd54426382..27e5fd494fbe 100644 --- a/sys/netinet/sctp.h +++ b/sys/netinet/sctp.h @@ -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 diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 1af76c3eaa64..e2661711c679 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -6804,6 +6804,10 @@ sctp_sendall_completes(void *ptr, uint32_t val SCTP_UNUSED) */ /* 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, struct mbuf *m, 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, struct mbuf *m, 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,