svn commit: r361522 - releng/11.4/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Tue May 26 15:48:29 UTC 2020
Author: tuexen
Date: Tue May 26 15:48:27 2020
New Revision: 361522
URL: https://svnweb.freebsd.org/changeset/base/361522
Log:
MFS r361469: Fix bug in PR-SCTP
Only drop DATA chunk with lower priorities as specified in RFC 7496.
This issue was found by looking at a reproducer generated by syzkaller.
MFS r361472: Improve SCTP iterator
Ensure that the SCTP iterator runs with an stcb and inp, which belong to
each other.
MFS r361473: Improve stcb handling during teardown
Ensure that an stcb is not dereferenced when it is about to be freed.
This issue was found by SYZKALLER.
MFS r361476: Improve ASCONF handling
Avoid an integer underflow.
Approved by: re(gjb)
Modified:
releng/11.4/sys/netinet/sctp_asconf.c
releng/11.4/sys/netinet/sctp_indata.c
releng/11.4/sys/netinet/sctp_indata.h
releng/11.4/sys/netinet/sctp_output.c
releng/11.4/sys/netinet/sctputil.c
Directory Properties:
releng/11.4/ (props changed)
Modified: releng/11.4/sys/netinet/sctp_asconf.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_asconf.c Tue May 26 15:48:06 2020 (r361521)
+++ releng/11.4/sys/netinet/sctp_asconf.c Tue May 26 15:48:27 2020 (r361522)
@@ -1797,9 +1797,9 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
} /* switch */
/* update remaining ASCONF-ACK message length to process */
- ack_length -= SCTP_SIZE32(param_length);
- if (ack_length <= 0) {
- /* no more data in the mbuf chain */
+ if (ack_length > SCTP_SIZE32(param_length)) {
+ ack_length -= SCTP_SIZE32(param_length);
+ } else {
break;
}
offset += SCTP_SIZE32(param_length);
Modified: releng/11.4/sys/netinet/sctp_indata.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.c Tue May 26 15:48:06 2020 (r361521)
+++ releng/11.4/sys/netinet/sctp_indata.c Tue May 26 15:48:27 2020 (r361522)
@@ -162,6 +162,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
read_queue_e->data = dm;
read_queue_e->stcb = stcb;
read_queue_e->port_from = stcb->rport;
+ if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ read_queue_e->do_not_ref_stcb = 1;
+ }
failed_build:
return (read_queue_e);
}
@@ -773,6 +776,7 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_
atomic_add_int(&nc->whoFrom->ref_count, 1);
nc->stcb = control->stcb;
nc->port_from = control->port_from;
+ nc->do_not_ref_stcb = control->do_not_ref_stcb;
}
static void
Modified: releng/11.4/sys/netinet/sctp_indata.h
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.h Tue May 26 15:48:06 2020 (r361521)
+++ releng/11.4/sys/netinet/sctp_indata.h Tue May 26 15:48:27 2020 (r361522)
@@ -66,6 +66,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
(_ctl)->data = dm; \
(_ctl)->stcb = (in_it); \
(_ctl)->port_from = (in_it)->rport; \
+ if ((in_it)->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { \
+ (_ctl)->do_not_ref_stcb = 1; \
+ }\
} \
} while (0)
Modified: releng/11.4/sys/netinet/sctp_output.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_output.c Tue May 26 15:48:06 2020 (r361521)
+++ releng/11.4/sys/netinet/sctp_output.c Tue May 26 15:48:27 2020 (r361522)
@@ -6198,11 +6198,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
* This one is PR-SCTP AND buffer space
* limited type
*/
- if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
+ if (chk->rec.data.timetodrop.tv_sec > (long)srcv->sinfo_timetolive) {
/*
* Lower numbers equates to higher
* priority so if the one we are
- * looking at has a larger or equal
+ * looking at has a larger
* priority we want to drop the data
* and NOT retransmit it.
*/
@@ -6233,7 +6233,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
/* Here we must move to the sent queue and mark */
if (PR_SCTP_BUF_ENABLED(chk->flags)) {
- if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
+ if (chk->rec.data.timetodrop.tv_sec > (long)srcv->sinfo_timetolive) {
if (chk->data) {
/*
* We release the book_size
@@ -12614,7 +12614,7 @@ sctp_lower_sosend(struct socket *so,
top = SCTP_HEADER_TO_CHAIN(i_pak);
sndlen = SCTP_HEADER_LEN(i_pak);
}
- SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zu\n",
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zd\n",
(void *)addr,
sndlen);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
Modified: releng/11.4/sys/netinet/sctputil.c
==============================================================================
--- releng/11.4/sys/netinet/sctputil.c Tue May 26 15:48:06 2020 (r361521)
+++ releng/11.4/sys/netinet/sctputil.c Tue May 26 15:48:27 2020 (r361522)
@@ -1409,6 +1409,7 @@ select_a_new_ep:
}
tinp = it->inp;
it->inp = LIST_NEXT(it->inp, sctp_list);
+ it->stcb = NULL;
SCTP_INP_RUNLOCK(tinp);
if (it->inp == NULL) {
goto done_with_iterator;
@@ -1478,6 +1479,9 @@ select_a_new_ep:
atomic_add_int(&it->stcb->asoc.refcnt, -1);
iteration_count = 0;
}
+ KASSERT(it->inp == it->stcb->sctp_ep,
+ ("%s: stcb %p does not belong to inp %p, but inp %p",
+ __func__, it->stcb, it->inp, it->stcb->sctp_ep));
/* run function on this one */
(*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val);
@@ -1510,6 +1514,7 @@ no_stcb:
} else {
it->inp = LIST_NEXT(it->inp, sctp_list);
}
+ it->stcb = NULL;
if (it->inp == NULL) {
goto done_with_iterator;
}
More information about the svn-src-releng
mailing list