aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2021-08-18 22:31:35 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2021-08-18 22:33:28 +0000
commiteba8e643b19cb7acd7c9a79acfab376b3967f20d (patch)
treea1f4e4e78cb17eaaf0bbc33e63c64694955ca16f
parentc7cf100aafb4cb881e05a5153de152907f6c07f3 (diff)
downloadsrc-eba8e643b19cb7acd7c9a79acfab376b3967f20d.tar.gz
src-eba8e643b19cb7acd7c9a79acfab376b3967f20d.zip
sctp: improve handling of INIT chunks with invalid parameters
MFC after: 3 days
-rw-r--r--sys/netinet/sctp_input.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index ed15b81ba3e5..66ec2d6a577a 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -86,7 +86,7 @@ static void
sctp_handle_init(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
- struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_no_unlock,
+ struct sctp_tcb *stcb, struct sctp_nets *net,
uint8_t mflowtype, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
@@ -100,17 +100,17 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
}
/* Validate parameters */
init = &cp->init;
- if ((ntohl(init->initiate_tag) == 0) ||
- (ntohl(init->a_rwnd) < SCTP_MIN_RWND) ||
+ if (ntohl(init->initiate_tag) == 0) {
+ goto outnow;
+ }
+ if ((ntohl(init->a_rwnd) < SCTP_MIN_RWND) ||
(ntohs(init->num_inbound_streams) == 0) ||
(ntohs(init->num_outbound_streams) == 0)) {
/* protocol error... send abort */
op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
- sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
- mflowtype, mflowid,
+ sctp_send_abort(m, iphlen, src, dst, sh, init->initiate_tag, op_err,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
- if (stcb)
- *abort_no_unlock = 1;
goto outnow;
}
if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
@@ -118,11 +118,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
/* auth parameter(s) error... send abort */
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Problem with AUTH parameters");
- sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
- mflowtype, mflowid,
+ sctp_send_abort(m, iphlen, src, dst, sh, init->initiate_tag, op_err,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
- if (stcb)
- *abort_no_unlock = 1;
goto outnow;
}
/* We are only accepting if we have a listening socket. */
@@ -4613,20 +4611,22 @@ process_control_chunks:
/* Honor our resource limit. */
if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
- sctp_abort_association(inp, stcb, m, iphlen,
- src, dst, sh, op_err,
- mflowtype, mflowid,
+ sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
+ mflowtype, mflowid, inp->fibnum,
vrf_id, port);
*offset = length;
+ if (stcb != NULL) {
+ SCTP_TCB_UNLOCK(stcb);
+ }
return (NULL);
}
sctp_handle_init(m, iphlen, *offset, src, dst, sh,
(struct sctp_init_chunk *)ch, inp,
- stcb, *netp, &abort_no_unlock,
+ stcb, *netp,
mflowtype, mflowid,
vrf_id, port);
*offset = length;
- if ((!abort_no_unlock) && (stcb != NULL)) {
+ if (stcb != NULL) {
SCTP_TCB_UNLOCK(stcb);
}
return (NULL);