3535#include <net/sctp/sctp.h>
3636#include <net/sctp/sm.h>
3737
38+ static int sctp_stream_alloc_out (struct sctp_stream * stream , __u16 outcnt ,
39+ gfp_t gfp )
40+ {
41+ struct sctp_stream_out * out ;
42+
43+ out = kmalloc_array (outcnt , sizeof (* out ), gfp );
44+ if (!out )
45+ return - ENOMEM ;
46+
47+ if (stream -> out ) {
48+ memcpy (out , stream -> out , min (outcnt , stream -> outcnt ) *
49+ sizeof (* out ));
50+ kfree (stream -> out );
51+ }
52+
53+ if (outcnt > stream -> outcnt )
54+ memset (out + stream -> outcnt , 0 ,
55+ (outcnt - stream -> outcnt ) * sizeof (* out ));
56+
57+ stream -> out = out ;
58+
59+ return 0 ;
60+ }
61+
3862int sctp_stream_init (struct sctp_stream * stream , __u16 outcnt , __u16 incnt ,
3963 gfp_t gfp )
4064{
@@ -48,11 +72,9 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
4872 if (outcnt == stream -> outcnt )
4973 goto in ;
5074
51- kfree (stream -> out );
52-
53- stream -> out = kcalloc (outcnt , sizeof (* stream -> out ), gfp );
54- if (!stream -> out )
55- return - ENOMEM ;
75+ i = sctp_stream_alloc_out (stream , outcnt , gfp );
76+ if (i )
77+ return i ;
5678
5779 stream -> outcnt = outcnt ;
5880 for (i = 0 ; i < stream -> outcnt ; i ++ )
@@ -276,15 +298,9 @@ int sctp_send_add_streams(struct sctp_association *asoc,
276298 }
277299
278300 if (out ) {
279- struct sctp_stream_out * streamout ;
280-
281- streamout = krealloc (stream -> out , outcnt * sizeof (* streamout ),
282- GFP_KERNEL );
283- if (!streamout )
301+ retval = sctp_stream_alloc_out (stream , outcnt , GFP_KERNEL );
302+ if (retval )
284303 goto out ;
285-
286- memset (streamout + stream -> outcnt , 0 , out * sizeof (* streamout ));
287- stream -> out = streamout ;
288304 }
289305
290306 chunk = sctp_make_strreset_addstrm (asoc , out , in );
@@ -682,10 +698,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
682698 struct sctp_strreset_addstrm * addstrm = param .v ;
683699 struct sctp_stream * stream = & asoc -> stream ;
684700 __u32 result = SCTP_STRRESET_DENIED ;
685- struct sctp_stream_out * streamout ;
686701 struct sctp_chunk * chunk = NULL ;
687702 __u32 request_seq , outcnt ;
688703 __u16 out , i ;
704+ int ret ;
689705
690706 request_seq = ntohl (addstrm -> request_seq );
691707 if (TSN_lt (asoc -> strreset_inseq , request_seq ) ||
@@ -714,14 +730,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
714730 if (!out || outcnt > SCTP_MAX_STREAM )
715731 goto out ;
716732
717- streamout = krealloc (stream -> out , outcnt * sizeof (* streamout ),
718- GFP_ATOMIC );
719- if (!streamout )
733+ ret = sctp_stream_alloc_out (stream , outcnt , GFP_ATOMIC );
734+ if (ret )
720735 goto out ;
721736
722- memset (streamout + stream -> outcnt , 0 , out * sizeof (* streamout ));
723- stream -> out = streamout ;
724-
725737 chunk = sctp_make_strreset_addstrm (asoc , out , 0 );
726738 if (!chunk )
727739 goto out ;
0 commit comments