On Thu, Jun 27, 2019 at 07:48:10PM -0300, Marcelo Ricardo Leitner wrote: > It allocates the extended area for outbound streams only on sendmsg > calls, if they are not yet allocated. When using the priority > stream scheduler, this initialization may imply into a subsequent > allocation, which may fail. In this case, it was aborting the stream > scheduler initialization but leaving the ->ext pointer (allocated) in > there, thus in a partially initialized state. On a subsequent call to > sendmsg, it would notice the ->ext pointer in there, and trip on > uninitialized stuff when trying to schedule the data chunk. > > The fix is undo the ->ext initialization if the stream scheduler > initialization fails and avoid the partially initialized state. > > Although syzkaller bisected this to commit 4ff40b86262b ("sctp: set > chunk transport correctly when it's a new asoc"), this bug was actually > introduced on the commit I marked below. > > Reported-by: syzbot+c1a380d42b190ad1e559@xxxxxxxxxxxxxxxxxxxxxxxxx > Fixes: 5bbbbe32a431 ("sctp: introduce stream scheduler foundations") > Tested-by: Xin Long <lucien.xin@xxxxxxxxx> > Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@xxxxxxxxx> > --- > net/sctp/stream.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/net/sctp/stream.c b/net/sctp/stream.c > index 93ed07877337eace4ef7f4775dda5868359ada37..25946604af85c09917e63e5c4a8d7d6fa2caebc4 100644 > --- a/net/sctp/stream.c > +++ b/net/sctp/stream.c > @@ -153,13 +153,20 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, > int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid) > { > struct sctp_stream_out_ext *soute; > + int ret; > > soute = kzalloc(sizeof(*soute), GFP_KERNEL); > if (!soute) > return -ENOMEM; > SCTP_SO(stream, sid)->ext = soute; > > - return sctp_sched_init_sid(stream, sid, GFP_KERNEL); > + ret = sctp_sched_init_sid(stream, sid, GFP_KERNEL); > + if (ret) { > + kfree(SCTP_SO(stream, sid)->ext); > + SCTP_SO(stream, sid)->ext = NULL; > + } > + > + return ret; > } > > void sctp_stream_free(struct sctp_stream *stream) > -- > 2.21.0 > > Acked-by: Neil Horman <nhorman@xxxxxxxxxx>