aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2008-12-25 19:58:11 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-25 19:58:11 -0500
commit9fcb95a105758b81ef0131cd18e2db5149f13e95 (patch)
treefc38a5c1a91a5137bc385b8bdc7cb30539776222
parentaea3c5c05d2c409e93bfa80dcedc06af7da6c13b (diff)
sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
If FWD-TSN chunk is received with bad stream ID, the sctp will not do the validity check, this may cause memory overflow when overwrite the TSN of the stream ID. The FORWARD-TSN chunk is like this: FORWARD-TSN chunk Type = 192 Flags = 0 Length = 172 NewTSN = 99 Stream = 10000 StreamSequence = 0xFFFF This patch fix this problem by discard the chunk if stream ID is not less than MIS. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sctp/sm_statefuns.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 9f2a3eb656e5..1c4e5d6c29c0 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3689,6 +3689,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3689{ 3689{
3690 struct sctp_chunk *chunk = arg; 3690 struct sctp_chunk *chunk = arg;
3691 struct sctp_fwdtsn_hdr *fwdtsn_hdr; 3691 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3692 struct sctp_fwdtsn_skip *skip;
3692 __u16 len; 3693 __u16 len;
3693 __u32 tsn; 3694 __u32 tsn;
3694 3695
@@ -3718,6 +3719,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3718 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) 3719 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3719 goto discard_noforce; 3720 goto discard_noforce;
3720 3721
3722 /* Silently discard the chunk if stream-id is not valid */
3723 sctp_walk_fwdtsn(skip, chunk) {
3724 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
3725 goto discard_noforce;
3726 }
3727
3721 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); 3728 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3722 if (len > sizeof(struct sctp_fwdtsn_hdr)) 3729 if (len > sizeof(struct sctp_fwdtsn_hdr))
3723 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, 3730 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
@@ -3749,6 +3756,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3749{ 3756{
3750 struct sctp_chunk *chunk = arg; 3757 struct sctp_chunk *chunk = arg;
3751 struct sctp_fwdtsn_hdr *fwdtsn_hdr; 3758 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3759 struct sctp_fwdtsn_skip *skip;
3752 __u16 len; 3760 __u16 len;
3753 __u32 tsn; 3761 __u32 tsn;
3754 3762
@@ -3778,6 +3786,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3778 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) 3786 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3779 goto gen_shutdown; 3787 goto gen_shutdown;
3780 3788
3789 /* Silently discard the chunk if stream-id is not valid */
3790 sctp_walk_fwdtsn(skip, chunk) {
3791 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
3792 goto gen_shutdown;
3793 }
3794
3781 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); 3795 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3782 if (len > sizeof(struct sctp_fwdtsn_hdr)) 3796 if (len > sizeof(struct sctp_fwdtsn_hdr))
3783 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, 3797 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,