35
35
#include <net/sctp/sctp.h>
36
36
#include <net/sctp/sm.h>
37
37
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
+
38
62
int sctp_stream_init (struct sctp_stream * stream , __u16 outcnt , __u16 incnt ,
39
63
gfp_t gfp )
40
64
{
@@ -48,11 +72,9 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
48
72
if (outcnt == stream -> outcnt )
49
73
goto in ;
50
74
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 ;
56
78
57
79
stream -> outcnt = outcnt ;
58
80
for (i = 0 ; i < stream -> outcnt ; i ++ )
@@ -276,15 +298,9 @@ int sctp_send_add_streams(struct sctp_association *asoc,
276
298
}
277
299
278
300
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 )
284
303
goto out ;
285
-
286
- memset (streamout + stream -> outcnt , 0 , out * sizeof (* streamout ));
287
- stream -> out = streamout ;
288
304
}
289
305
290
306
chunk = sctp_make_strreset_addstrm (asoc , out , in );
@@ -682,10 +698,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
682
698
struct sctp_strreset_addstrm * addstrm = param .v ;
683
699
struct sctp_stream * stream = & asoc -> stream ;
684
700
__u32 result = SCTP_STRRESET_DENIED ;
685
- struct sctp_stream_out * streamout ;
686
701
struct sctp_chunk * chunk = NULL ;
687
702
__u32 request_seq , outcnt ;
688
703
__u16 out , i ;
704
+ int ret ;
689
705
690
706
request_seq = ntohl (addstrm -> request_seq );
691
707
if (TSN_lt (asoc -> strreset_inseq , request_seq ) ||
@@ -714,14 +730,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
714
730
if (!out || outcnt > SCTP_MAX_STREAM )
715
731
goto out ;
716
732
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 )
720
735
goto out ;
721
736
722
- memset (streamout + stream -> outcnt , 0 , out * sizeof (* streamout ));
723
- stream -> out = streamout ;
724
-
725
737
chunk = sctp_make_strreset_addstrm (asoc , out , 0 );
726
738
if (!chunk )
727
739
goto out ;
0 commit comments