|
@@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
|
|
const struct sctp_endpoint *ep,
|
|
const struct sctp_endpoint *ep,
|
|
const struct sctp_association *asoc,
|
|
const struct sctp_association *asoc,
|
|
const sctp_subtype_t type,
|
|
const sctp_subtype_t type,
|
|
- void *arg,
|
|
|
|
|
|
+ void *arg, void *ext,
|
|
sctp_cmd_seq_t *commands);
|
|
sctp_cmd_seq_t *commands);
|
|
|
|
|
|
static sctp_disposition_t sctp_sf_violation_ctsn(
|
|
static sctp_disposition_t sctp_sf_violation_ctsn(
|
|
@@ -3425,7 +3425,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
|
|
addr_param = (union sctp_addr_param *)hdr->params;
|
|
addr_param = (union sctp_addr_param *)hdr->params;
|
|
length = ntohs(addr_param->p.length);
|
|
length = ntohs(addr_param->p.length);
|
|
if (length < sizeof(sctp_paramhdr_t))
|
|
if (length < sizeof(sctp_paramhdr_t))
|
|
- return sctp_sf_violation_paramlen(ep, asoc, type,
|
|
|
|
|
|
+ return sctp_sf_violation_paramlen(ep, asoc, type, arg,
|
|
(void *)addr_param, commands);
|
|
(void *)addr_param, commands);
|
|
|
|
|
|
/* Verify the ASCONF chunk before processing it. */
|
|
/* Verify the ASCONF chunk before processing it. */
|
|
@@ -3433,8 +3433,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
|
|
(sctp_paramhdr_t *)((void *)addr_param + length),
|
|
(sctp_paramhdr_t *)((void *)addr_param + length),
|
|
(void *)chunk->chunk_end,
|
|
(void *)chunk->chunk_end,
|
|
&err_param))
|
|
&err_param))
|
|
- return sctp_sf_violation_paramlen(ep, asoc, type,
|
|
|
|
- (void *)&err_param, commands);
|
|
|
|
|
|
+ return sctp_sf_violation_paramlen(ep, asoc, type, arg,
|
|
|
|
+ (void *)err_param, commands);
|
|
|
|
|
|
/* ADDIP 5.2 E1) Compare the value of the serial number to the value
|
|
/* ADDIP 5.2 E1) Compare the value of the serial number to the value
|
|
* the endpoint stored in a new association variable
|
|
* the endpoint stored in a new association variable
|
|
@@ -3542,8 +3542,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
|
|
(sctp_paramhdr_t *)addip_hdr->params,
|
|
(sctp_paramhdr_t *)addip_hdr->params,
|
|
(void *)asconf_ack->chunk_end,
|
|
(void *)asconf_ack->chunk_end,
|
|
&err_param))
|
|
&err_param))
|
|
- return sctp_sf_violation_paramlen(ep, asoc, type,
|
|
|
|
- (void *)&err_param, commands);
|
|
|
|
|
|
+ return sctp_sf_violation_paramlen(ep, asoc, type, arg,
|
|
|
|
+ (void *)err_param, commands);
|
|
|
|
|
|
if (last_asconf) {
|
|
if (last_asconf) {
|
|
addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
|
|
addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
|
|
@@ -4240,12 +4240,38 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
|
|
const struct sctp_endpoint *ep,
|
|
const struct sctp_endpoint *ep,
|
|
const struct sctp_association *asoc,
|
|
const struct sctp_association *asoc,
|
|
const sctp_subtype_t type,
|
|
const sctp_subtype_t type,
|
|
- void *arg,
|
|
|
|
- sctp_cmd_seq_t *commands) {
|
|
|
|
- static const char err_str[] = "The following parameter had invalid length:";
|
|
|
|
|
|
+ void *arg, void *ext,
|
|
|
|
+ sctp_cmd_seq_t *commands)
|
|
|
|
+{
|
|
|
|
+ struct sctp_chunk *chunk = arg;
|
|
|
|
+ struct sctp_paramhdr *param = ext;
|
|
|
|
+ struct sctp_chunk *abort = NULL;
|
|
|
|
|
|
- return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
|
|
|
|
- sizeof(err_str));
|
|
|
|
|
|
+ if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
|
|
|
|
+ goto discard;
|
|
|
|
+
|
|
|
|
+ /* Make the abort chunk. */
|
|
|
|
+ abort = sctp_make_violation_paramlen(asoc, chunk, param);
|
|
|
|
+ if (!abort)
|
|
|
|
+ goto nomem;
|
|
|
|
+
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
|
|
|
+ SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
|
|
|
|
+
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
|
|
|
|
+ SCTP_ERROR(ECONNABORTED));
|
|
|
|
+ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
|
|
|
+ SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
|
|
|
|
+ SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
|
|
|
|
+
|
|
|
|
+discard:
|
|
|
|
+ sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
|
|
|
|
+
|
|
|
|
+ SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
|
|
|
|
+
|
|
|
|
+ return SCTP_DISPOSITION_ABORT;
|
|
|
|
+nomem:
|
|
|
|
+ return SCTP_DISPOSITION_NOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
/* Handle a protocol violation when the peer trying to advance the
|
|
/* Handle a protocol violation when the peer trying to advance the
|