From e6dcce69caf63b111d7618e84e27c7a558e0ef1d Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Thu, 7 Mar 2019 08:43:20 +0000 Subject: [PATCH] After removing an entry from the stream scheduler list, set the pointers to NULL, since we are checking for it in case the element gets inserted again. This issue was found by running syzkaller. MFC after: 3 days --- sys/netinet/sctp_ss_functions.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sys/netinet/sctp_ss_functions.c b/sys/netinet/sctp_ss_functions.c index a7e3133f39fa..fd0dd14f20f7 100644 --- a/sys/netinet/sctp_ss_functions.c +++ b/sys/netinet/sctp_ss_functions.c @@ -78,9 +78,10 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTP_TCB_SEND_LOCK(stcb); } while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) { - struct sctp_stream_out *strq = TAILQ_FIRST(&asoc->ss_data.out.wheel); + struct sctp_stream_out *strq; - TAILQ_REMOVE(&asoc->ss_data.out.wheel, TAILQ_FIRST(&asoc->ss_data.out.wheel), ss_params.rr.next_spoke); + strq = TAILQ_FIRST(&asoc->ss_data.out.wheel); + TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke); strq->ss_params.rr.next_spoke.tqe_next = NULL; strq->ss_params.rr.next_spoke.tqe_prev = NULL; } @@ -793,12 +794,17 @@ static void sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc, int clear_values, int holds_lock) { + struct sctp_stream_queue_pending *sp; + if (clear_values) { if (holds_lock == 0) { SCTP_TCB_SEND_LOCK(stcb); } while (!TAILQ_EMPTY(&asoc->ss_data.out.list)) { - TAILQ_REMOVE(&asoc->ss_data.out.list, TAILQ_FIRST(&asoc->ss_data.out.list), ss_next); + sp = TAILQ_FIRST(&asoc->ss_data.out.list); + TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next); + sp->ss_next.tqe_next = NULL; + sp->ss_next.tqe_prev = NULL; } if (holds_lock == 0) { SCTP_TCB_SEND_UNLOCK(stcb); @@ -861,6 +867,8 @@ sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc, ((sp->ss_next.tqe_next != NULL) || (sp->ss_next.tqe_prev != NULL))) { TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next); + sp->ss_next.tqe_next = NULL; + sp->ss_next.tqe_prev = NULL; } if (holds_lock == 0) { SCTP_TCB_SEND_UNLOCK(stcb);