diff options
author | Xin Long <lucien.xin@gmail.com> | 2017-06-20 10:05:11 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-20 21:32:55 +0200 |
commit | 5ee8aa689780f2c19702fe3768a3103b9c07d72e (patch) | |
tree | 51756f9ea4bb01a443a783b5cb22f0f587dcff9b /net/sctp/sm_sideeffect.c | |
parent | sctp: uncork the old asoc before changing to the new one (diff) | |
download | linux-5ee8aa689780f2c19702fe3768a3103b9c07d72e.tar.xz linux-5ee8aa689780f2c19702fe3768a3103b9c07d72e.zip |
sctp: handle errors when updating asoc
It's a bad thing not to handle errors when updating asoc. The memory
allocation failure in any of the functions called in sctp_assoc_update()
would cause sctp to work unexpectedly.
This patch is to fix it by aborting the asoc and reporting the error when
any of these functions fails.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 76235663fe06..dfe1fcb520ba 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -818,6 +818,28 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; } +static void sctp_cmd_assoc_update(sctp_cmd_seq_t *cmds, + struct sctp_association *asoc, + struct sctp_association *new) +{ + struct net *net = sock_net(asoc->base.sk); + struct sctp_chunk *abort; + + if (!sctp_assoc_update(asoc, new)) + return; + + abort = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t)); + if (abort) { + sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); + sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + } + sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED)); + sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED, + SCTP_PERR(SCTP_ERROR_RSRC_LOW)); + SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); + SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); +} + /* Helper function to change the state of an association. */ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, struct sctp_association *asoc, @@ -1294,7 +1316,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, break; case SCTP_CMD_UPDATE_ASSOC: - sctp_assoc_update(asoc, cmd->obj.asoc); + sctp_cmd_assoc_update(commands, asoc, cmd->obj.asoc); break; case SCTP_CMD_PURGE_OUTQUEUE: |