mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
Two bugs:
- Locks were not being unlocked when an invalid size chunk is sent in. - When a notification comes in, we cannot use it to look up the fragment interleave stream information since its not on a stream.
This commit is contained in:
parent
d0a68c2747
commit
6114cd961a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169295
@ -3938,6 +3938,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
printf("Bad size on sack chunk .. to small\n");
|
||||
}
|
||||
#endif
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -3970,6 +3972,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
}
|
||||
if (abort_now) {
|
||||
/* ABORT signal from sack processing */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -3996,6 +4000,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
#endif /* SCTP_DEBUG */
|
||||
if (chk_length != sizeof(struct sctp_heartbeat_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4024,6 +4030,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
#endif /* SCTP_DEBUG */
|
||||
if (chk_length != sizeof(struct sctp_shutdown_chunk)) {
|
||||
*offset = length;
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
return (NULL);
|
||||
|
||||
} {
|
||||
@ -4211,6 +4219,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
/* He's alive so give him credit */
|
||||
if (chk_length != sizeof(struct sctp_ecne_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4227,6 +4237,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
/* He's alive so give him credit */
|
||||
if (chk_length != sizeof(struct sctp_cwr_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4274,6 +4286,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
#endif /* SCTP_DEBUG */
|
||||
if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4291,6 +4305,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
#endif /* SCTP_DEBUG */
|
||||
if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4327,6 +4343,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
chk_length, chunk_buf);
|
||||
if (chk_length < sizeof(struct sctp_stream_reset_tsn_req)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4359,6 +4377,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
/* re-get it all please */
|
||||
if (chk_length < sizeof(struct sctp_pktdrop_chunk)) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
@ -4392,6 +4412,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if ((chk_length < (sizeof(struct sctp_auth_chunk))) ||
|
||||
(chk_length > (sizeof(struct sctp_auth_chunk) + SCTP_AUTH_DIGEST_LEN_MAX))) {
|
||||
/* Its not ours */
|
||||
if (locked_tcb)
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -4526,7 +4526,8 @@ sctp_sorecvmsg(struct socket *so,
|
||||
} else {
|
||||
in_flags = 0;
|
||||
}
|
||||
slen = uio->uio_resid;
|
||||
if (uio)
|
||||
slen = uio->uio_resid;
|
||||
/* Pull in and set up our int flags */
|
||||
if (in_flags & MSG_OOB) {
|
||||
/* Out of band's NOT supported */
|
||||
@ -4553,11 +4554,11 @@ sctp_sorecvmsg(struct socket *so,
|
||||
in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
|
||||
#ifdef SCTP_RECV_RWND_LOGGING
|
||||
sctp_misc_ints(SCTP_SORECV_ENTER,
|
||||
rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid);
|
||||
rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, slen);
|
||||
#endif
|
||||
#ifdef SCTP_RECV_RWND_LOGGING
|
||||
sctp_misc_ints(SCTP_SORECV_ENTERPL,
|
||||
rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid);
|
||||
rwnd_req, block_allowed, so->so_rcv.sb_cc, slen);
|
||||
#endif
|
||||
|
||||
|
||||
@ -4592,7 +4593,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
/* we need to wait for data */
|
||||
#ifdef SCTP_RECV_DETAIL_RWND_LOGGING
|
||||
sctp_misc_ints(SCTP_SORECV_BLOCKSA,
|
||||
0, 0, so->so_rcv.sb_cc, uio->uio_resid);
|
||||
0, 0, so->so_rcv.sb_cc, slen);
|
||||
#endif
|
||||
if ((so->so_rcv.sb_cc == 0) &&
|
||||
((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
|
||||
@ -4767,6 +4768,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
while (ctl) {
|
||||
if ((ctl->stcb != control->stcb) && (ctl->length) &&
|
||||
(ctl->some_taken ||
|
||||
(ctl->spec_flags & M_NOTIFICATION) ||
|
||||
((ctl->do_not_ref_stcb == 0) &&
|
||||
(ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
|
||||
) {
|
||||
@ -4782,6 +4784,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
(ctl->length) &&
|
||||
((ctl->some_taken) ||
|
||||
((ctl->do_not_ref_stcb == 0) &&
|
||||
- ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
|
||||
(ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
|
||||
) {
|
||||
/*-
|
||||
@ -4852,7 +4855,9 @@ sctp_sorecvmsg(struct socket *so,
|
||||
stcb->freed_by_sorcv_sincelast = 0;
|
||||
}
|
||||
}
|
||||
if (stcb && control->do_not_ref_stcb == 0) {
|
||||
if (stcb &&
|
||||
((control->spec_flags & M_NOTIFICATION) == 0) &&
|
||||
control->do_not_ref_stcb == 0) {
|
||||
stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
|
||||
}
|
||||
/* First lets get off the sinfo and sockaddr info */
|
||||
@ -5014,7 +5019,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
if ((SCTP_BUF_NEXT(m) == NULL) &&
|
||||
(control->end_added)) {
|
||||
out_flags |= MSG_EOR;
|
||||
if (control->do_not_ref_stcb == 0)
|
||||
if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
|
||||
control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
|
||||
}
|
||||
if (control->spec_flags & M_NOTIFICATION) {
|
||||
@ -5287,12 +5292,12 @@ sctp_sorecvmsg(struct socket *so,
|
||||
/* he aborted, or is done i.e.did a shutdown */
|
||||
out_flags |= MSG_EOR;
|
||||
if (control->pdapi_aborted) {
|
||||
if (control->do_not_ref_stcb == 0)
|
||||
if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
|
||||
control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
|
||||
|
||||
out_flags |= MSG_TRUNC;
|
||||
} else {
|
||||
if (control->do_not_ref_stcb == 0)
|
||||
if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
|
||||
control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
|
||||
}
|
||||
goto done_with_control;
|
||||
@ -5343,7 +5348,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
}
|
||||
if (control->end_added) {
|
||||
out_flags |= MSG_EOR;
|
||||
if (control->do_not_ref_stcb == 0)
|
||||
if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
|
||||
control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
|
||||
}
|
||||
if (control->spec_flags & M_NOTIFICATION) {
|
||||
@ -5409,7 +5414,7 @@ sctp_sorecvmsg(struct socket *so,
|
||||
out_flags |= MSG_EOR;
|
||||
if (control->pdapi_aborted) {
|
||||
out_flags |= MSG_TRUNC;
|
||||
if (control->do_not_ref_stcb == 0)
|
||||
if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
|
||||
control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
|
||||
}
|
||||
goto done_with_control;
|
||||
|
Loading…
Reference in New Issue
Block a user