Messages in this thread Patch in this message | | | Date | Thu, 22 Jan 2009 17:12:11 -0800 | From | Greg KH <> | Subject | [patch 20/46] sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID |
| |
2.6.28-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wei Yongjun <yjwei@cn.fujitsu.com>
[ Upstream commit: 9fcb95a105758b81ef0131cd18e2db5149f13e95 ]
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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- net/sctp/sm_statefuns.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -3691,6 +3691,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c { struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -3720,6 +3721,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) goto discard_noforce; + /* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { + if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) + goto discard_noforce; + } + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); if (len > sizeof(struct sctp_fwdtsn_hdr)) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, @@ -3751,6 +3758,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f { struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -3780,6 +3788,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) goto gen_shutdown; + /* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { + if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) + goto gen_shutdown; + } + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); if (len > sizeof(struct sctp_fwdtsn_hdr)) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
| |