diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
| -rw-r--r-- | net/sctp/sm_statefuns.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8848d329aa2c..7c622af2ce55 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen( | |||
| 119 | const struct sctp_endpoint *ep, | 119 | const struct sctp_endpoint *ep, |
| 120 | const struct sctp_association *asoc, | 120 | const struct sctp_association *asoc, |
| 121 | const sctp_subtype_t type, | 121 | const sctp_subtype_t type, |
| 122 | void *arg, | 122 | void *arg, void *ext, |
| 123 | sctp_cmd_seq_t *commands); | 123 | sctp_cmd_seq_t *commands); |
| 124 | 124 | ||
| 125 | static sctp_disposition_t sctp_sf_violation_ctsn( | 125 | static sctp_disposition_t sctp_sf_violation_ctsn( |
| @@ -3425,7 +3425,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
| 3425 | addr_param = (union sctp_addr_param *)hdr->params; | 3425 | addr_param = (union sctp_addr_param *)hdr->params; |
| 3426 | length = ntohs(addr_param->p.length); | 3426 | length = ntohs(addr_param->p.length); |
| 3427 | if (length < sizeof(sctp_paramhdr_t)) | 3427 | if (length < sizeof(sctp_paramhdr_t)) |
| 3428 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3428 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
| 3429 | (void *)addr_param, commands); | 3429 | (void *)addr_param, commands); |
| 3430 | 3430 | ||
| 3431 | /* Verify the ASCONF chunk before processing it. */ | 3431 | /* Verify the ASCONF chunk before processing it. */ |
| @@ -3433,8 +3433,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
| 3433 | (sctp_paramhdr_t *)((void *)addr_param + length), | 3433 | (sctp_paramhdr_t *)((void *)addr_param + length), |
| 3434 | (void *)chunk->chunk_end, | 3434 | (void *)chunk->chunk_end, |
| 3435 | &err_param)) | 3435 | &err_param)) |
| 3436 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3436 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
| 3437 | (void *)&err_param, commands); | 3437 | (void *)err_param, commands); |
| 3438 | 3438 | ||
| 3439 | /* ADDIP 5.2 E1) Compare the value of the serial number to the value | 3439 | /* ADDIP 5.2 E1) Compare the value of the serial number to the value |
| 3440 | * the endpoint stored in a new association variable | 3440 | * 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, | |||
| 3542 | (sctp_paramhdr_t *)addip_hdr->params, | 3542 | (sctp_paramhdr_t *)addip_hdr->params, |
| 3543 | (void *)asconf_ack->chunk_end, | 3543 | (void *)asconf_ack->chunk_end, |
| 3544 | &err_param)) | 3544 | &err_param)) |
| 3545 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3545 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
| 3546 | (void *)&err_param, commands); | 3546 | (void *)err_param, commands); |
| 3547 | 3547 | ||
| 3548 | if (last_asconf) { | 3548 | if (last_asconf) { |
| 3549 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; | 3549 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; |
| @@ -4240,12 +4240,38 @@ static sctp_disposition_t sctp_sf_violation_paramlen( | |||
| 4240 | const struct sctp_endpoint *ep, | 4240 | const struct sctp_endpoint *ep, |
| 4241 | const struct sctp_association *asoc, | 4241 | const struct sctp_association *asoc, |
| 4242 | const sctp_subtype_t type, | 4242 | const sctp_subtype_t type, |
| 4243 | void *arg, | 4243 | void *arg, void *ext, |
| 4244 | sctp_cmd_seq_t *commands) { | 4244 | sctp_cmd_seq_t *commands) |
| 4245 | static const char err_str[] = "The following parameter had invalid length:"; | 4245 | { |
| 4246 | struct sctp_chunk *chunk = arg; | ||
| 4247 | struct sctp_paramhdr *param = ext; | ||
| 4248 | struct sctp_chunk *abort = NULL; | ||
| 4246 | 4249 | ||
| 4247 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, | 4250 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) |
| 4248 | sizeof(err_str)); | 4251 | goto discard; |
| 4252 | |||
| 4253 | /* Make the abort chunk. */ | ||
| 4254 | abort = sctp_make_violation_paramlen(asoc, chunk, param); | ||
| 4255 | if (!abort) | ||
| 4256 | goto nomem; | ||
| 4257 | |||
| 4258 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); | ||
| 4259 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | ||
| 4260 | |||
| 4261 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
| 4262 | SCTP_ERROR(ECONNABORTED)); | ||
| 4263 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
| 4264 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); | ||
| 4265 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
| 4266 | |||
| 4267 | discard: | ||
| 4268 | sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); | ||
| 4269 | |||
| 4270 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
| 4271 | |||
| 4272 | return SCTP_DISPOSITION_ABORT; | ||
| 4273 | nomem: | ||
| 4274 | return SCTP_DISPOSITION_NOMEM; | ||
| 4249 | } | 4275 | } |
| 4250 | 4276 | ||
| 4251 | /* Handle a protocol violation when the peer trying to advance the | 4277 | /* Handle a protocol violation when the peer trying to advance the |
