aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2021-05-12 13:29:06 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2021-05-12 13:29:06 +0000
commit12dda000ed32efa16f59909a6294e4d4b5a771ba (patch)
tree9f950db4200e29d828abf75218639ecb8f64c5f3
parent8c39e25220bb88cd027d0c3b0fe86e52f6abd150 (diff)
downloadsrc-12dda000ed32efa16f59909a6294e4d4b5a771ba.tar.gz
src-12dda000ed32efa16f59909a6294e4d4b5a771ba.zip
sctp: fix locking in case of error handling during a restart
Thanks to Taylor Brandstetter for finding the issue and providing a patch for the userland stack. MFC after: 3 days
-rw-r--r--sys/netinet/sctp_input.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 050f30d145b7..f066cc100ac2 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -1395,6 +1395,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
vrf_id, net->port);
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 2;
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
/*
@@ -1409,9 +1410,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
(uint8_t *)&init_buf);
if (init_cp == NULL) {
/* could not pull a INIT chunk in cookie */
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
if (init_cp->ch.chunk_type != SCTP_INITIATION) {
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
/*
@@ -1424,9 +1427,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
(uint8_t *)&initack_buf);
if (initack_cp == NULL) {
/* could not pull INIT-ACK chunk in cookie */
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
@@ -1452,6 +1457,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 17;
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
switch (SCTP_GET_STATE(stcb)) {
@@ -1567,6 +1573,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 6;
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
/*
@@ -1592,6 +1599,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
mflowtype, mflowid, inp->fibnum,
vrf_id, port);
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
@@ -1622,6 +1630,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 7;
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}
if (how_indx < sizeof(asoc->cookie_how))
@@ -1952,6 +1961,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 16;
/* all other cases... */
+ SCTP_TCB_UNLOCK(stcb);
return (NULL);
}