From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-eopbgr80110.outbound.protection.outlook.com ([40.107.8.110]:24119 "EHLO EUR04-VI1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726660AbeIYPZ3 (ORCPT ); Tue, 25 Sep 2018 11:25:29 -0400 Subject: Re: WARNING in request_end To: Miklos Szeredi Cc: syzbot , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, syzkaller-bugs References: <0000000000006971fa05769d22f6@google.com> From: Kirill Tkhai Message-ID: <274aafd2-5076-6b14-f55e-360411fb8169@virtuozzo.com> Date: Tue, 25 Sep 2018 12:18:41 +0300 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On 24.09.2018 17:44, Miklos Szeredi wrote: > On Mon, Sep 24, 2018 at 2:29 PM, syzbot > wrote: >> Hello, >> >> syzbot found the following crash on: >> >> HEAD commit: 6bf4ca7fbc85 Linux 4.19-rc5 >> git tree: upstream >> console output: https://syzkaller.appspot.com/x/log.txt?x=159149c6400000 >> kernel config: https://syzkaller.appspot.com/x/.config?x=22a62640793a83c9 >> dashboard link: https://syzkaller.appspot.com/bug?extid=ef054c4d3f64cd7f7cec >> compiler: gcc (GCC) 8.0.1 20180413 (experimental) >> >> Unfortunately, I don't have any reproducer for this crash yet. >> >> IMPORTANT: if you fix the bug, please add the following tag to the commit: >> Reported-by: syzbot+ef054c4d3f64cd7f7cec@syzkaller.appspotmail.com >> >> WARNING: CPU: 0 PID: 9445 at fs/fuse/dev.c:390 request_end+0x82e/0xaa0 > > And there we have the bug likely caused by the set_bit(FR_SENT, ...) > not being inside the fpq->lock-ed region. > > So that needs to be fixed anyway, apparently. I can't confirm, since I haven't found yet the direct way, that set_bit() results in this stack... We have one more (unrelated) possible use-after-free here: cpu0 cpu1 fuse_dev_do_write() fuse_dev_do_write() req = request_find(fpq, oh.unique) ... spin_unlock(&fpq->lock) ... ... req = request_find(fpq, oh.unique) ... spin_unlock(&fpq->lock) queue_interrupt(&fc->iq, req); ... ... ... ... ... request freed ... ... queue_interrupt(&fc->iq, req); <- use after free Something like below is needed: @@ -1875,16 +1877,20 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, /* Is it an interrupt reply? */ if (req->intr_unique == oh.unique) { + __fuse_get_request(req); spin_unlock(&fpq->lock); err = -EINVAL; - if (nbytes != sizeof(struct fuse_out_header)) + if (nbytes != sizeof(struct fuse_out_header)) { + fuse_put_request(fc, req); goto err_finish; + } if (oh.error == -ENOSYS) fc->no_interrupt = 1; else if (oh.error == -EAGAIN) queue_interrupt(&fc->iq, req); + fuse_put_request(fc, req); fuse_copy_finish(cs); return nbytes;