[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20191220160559.GD5058@localhost.localdomain>
Date: Fri, 20 Dec 2019 13:05:59 -0300
From: Marcelo Ricardo Leitner <marcelo.leitner@...il.com>
To: syzbot <syzbot+9a1bc632e78a1a98488b@...kaller.appspotmail.com>
Cc: davem@...emloft.net, linux-kernel@...r.kernel.org,
linux-sctp@...r.kernel.org, lucien.xin@...il.com,
netdev@...r.kernel.org, nhorman@...driver.com,
syzkaller-bugs@...glegroups.com, vyasevich@...il.com
Subject: Re: general protection fault in sctp_stream_free (2)
On Fri, Dec 20, 2019 at 12:28:10PM -0300, Marcelo Ricardo Leitner wrote:
> On Thu, Dec 19, 2019 at 07:45:09PM -0800, syzbot wrote:
> > Hello,
> >
> > syzbot found the following crash on:
> >
> > HEAD commit: 6fa9a115 Merge branch 'stmmac-fixes'
> > git tree: net
> > console output: https://syzkaller.appspot.com/x/log.txt?x=10c4fe99e00000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=216dca5e1758db87
> > dashboard link: https://syzkaller.appspot.com/bug?extid=9a1bc632e78a1a98488b
> > compiler: gcc (GCC) 9.0.0 20181231 (experimental)
> > syz repro: https://syzkaller.appspot.com/x/repro.syz?x=178ada71e00000
> > C reproducer: https://syzkaller.appspot.com/x/repro.c?x=144f23a6e00000
> >
> > The bug was bisected to:
> >
> > commit 951c6db954a1adefab492f6da805decacabbd1a7
> > Author: Marcelo Ricardo Leitner <marcelo.leitner@...il.com>
> > Date: Tue Dec 17 01:01:16 2019 +0000
> >
> > sctp: fix memleak on err handling of stream initialization
>
> Ouch... this wasn't a good fix.
> When called from sctp_stream_init(), it is doing the right thing.
> But when called from sctp_send_add_streams(), it can't free the
> genradix. Ditto from sctp_process_strreset_addstrm_in().
Tentative fix. I'll post after additional tests.
--8<--
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 6a30392068a0..c1a100d2fed3 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -84,10 +84,8 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
return 0;
ret = genradix_prealloc(&stream->out, outcnt, gfp);
- if (ret) {
- genradix_free(&stream->out);
+ if (ret)
return ret;
- }
stream->outcnt = outcnt;
return 0;
@@ -102,10 +100,8 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt,
return 0;
ret = genradix_prealloc(&stream->in, incnt, gfp);
- if (ret) {
- genradix_free(&stream->in);
+ if (ret)
return ret;
- }
stream->incnt = incnt;
return 0;
@@ -123,7 +119,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
* a new one with new outcnt to save memory if needed.
*/
if (outcnt == stream->outcnt)
- goto in;
+ goto handle_in;
/* Filter out chunks queued on streams that won't exist anymore */
sched->unsched_all(stream);
@@ -132,24 +128,28 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
ret = sctp_stream_alloc_out(stream, outcnt, gfp);
if (ret)
- goto out;
+ goto out_err;
for (i = 0; i < stream->outcnt; i++)
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
-in:
+handle_in:
sctp_stream_interleave_init(stream);
if (!incnt)
goto out;
ret = sctp_stream_alloc_in(stream, incnt, gfp);
- if (ret) {
- sched->free(stream);
- genradix_free(&stream->out);
- stream->outcnt = 0;
- goto out;
- }
+ if (ret)
+ goto in_err;
+
+ goto out;
+in_err:
+ sched->free(stream);
+ genradix_free(&stream->in);
+out_err:
+ genradix_free(&stream->out);
+ stream->outcnt = 0;
out:
return ret;
}
Powered by blists - more mailing lists