On Wed, Apr 5, 2017 at 2:44 PM, Marcelo Ricardo Leitner <marcelo.leit...@gmail.com> wrote: > On Wed, Apr 05, 2017 at 06:48:45PM +0800, Xin Long wrote: >> On Wed, Apr 5, 2017 at 5:14 AM, Marcelo Ricardo Leitner >> <marcelo.leit...@gmail.com> wrote: >> > On Wed, Apr 05, 2017 at 01:29:19AM +0800, Xin Long wrote: >> >> On Tue, Apr 4, 2017 at 9:28 PM, Andrey Konovalov <andreyk...@google.com> >> >> wrote: >> >> > Hi, >> >> > >> >> > I've got the following error report while fuzzing the kernel with >> >> > syzkaller. >> >> > >> >> > On commit a71c9a1c779f2499fb2afc0553e543f18aff6edf (4.11-rc5). >> >> > >> >> > A reproducer and .config are attached. >> >> The script is pretty hard to reproduce the issue in my env. >> > >> > I didn't try running it but I also found the reproducer very complicated >> > to follow. Do you have any plans on having some PoC optimizer, so we can >> > have a more readable code? >> > strace is handy for filtering the noise, yes, but sometimes it doesn't >> > cut it. >> I got the script now: >> 1. create sk >> 2. set sk->sndbuf = x >> 3. sendmsg with size s1 (s1 < x) >> 4. sendmsg with size s2 (s1+s2 > x) >> 5. sendmsg with size s3 (wspace < 0), wait sndbuf, schedule out. >> 6. listen sk (abnormal operation on sctp client) >> 7. accept sk. >> >> In step 6, sk->sk_state = listening, then step 7 could get the first asoc >> from ep->asoc_list and alloc a new sk2, attach the asoc to sk2. >> >> after a while, sendmsg schedule in, but asoc->sk is sk2, !=sk. >> the same issue we fix for peeloff on commit dfcb9f4f99f1 ("sctp: deny >> peeloff operation on asocs with threads sleeping on it") happens. > > Yes. That explains why the asoc isn't dead by when sendmsg comes back, > and avoid that dead check. > >> >> But we should not fix it by the same way as for peeloff. the real reason >> causes this issue is on step 6, it should disallow listen on the established >> sk. > > Agreed. > >> >> The following fix should work for this, just similar with what >> inet_listen() did. >> >> @@ -7174,6 +7175,9 @@ int sctp_inet_listen(struct socket *sock, int backlog) >> if (sock->state != SS_UNCONNECTED) >> goto out; >> >> + if (!sctp_sstate(sk, LISTENING) && !sctp_sstate(sk,CLOSED)) >> + goto out; >> +
This fixes the report. Tested-by: Andrey Konovalov <andreyk...@google.com> Thanks! >> >> what do you think ? > > Yes, agreed. > Thanks! > > Marcelo