Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp255873imu; Thu, 8 Nov 2018 01:06:34 -0800 (PST) X-Google-Smtp-Source: AJdET5fzToywRx5wlKyC+A1C73u1R93LHXT4ruoYd3INlFIrZ5hF40JpCCO42Ol5tQvCvLpG+8uA X-Received: by 2002:a63:4566:: with SMTP id u38mr3134602pgk.4.1541667994194; Thu, 08 Nov 2018 01:06:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541667994; cv=none; d=google.com; s=arc-20160816; b=y91M+cZ0TbPXb3hM+BvJkxP/YI2d/UxXGErG1Ny9lnw4hkJIBWutzRju5mMwXMTUZq EY/unEF9Xf85KtV2StMLFZINjoTix0j1O0D8if0DB1Vjnbub/0J7j9Rztc4NMFHVFoxG jZTumzOWFtTAUPlJoESyHlAPJAKKCGAdSAbUo6c7DmKb72syY9Jat/sfcJQ6hEqCxPIf YPVRgDFH4My8I39eMzh7QKSkwcuxQ86iZ+IdlAVCibenq1XV+JDyBKqb+/XWoGwql1DG W49T5WK4C1rgIK19UweNaRYrSVEyuUUG7Q6Kq7rBVJqCTrooOCtL2+1s96iVXkyC8QD+ 9ECw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:to:from:subject; bh=F+E8xg9dTlBJi1cIK0RFs9ZMx/L4kMnGGOPuLf8jumk=; b=TQCfWS5n4JPvLOPc6UbAUYXYN58q72Ur0k644K0owabZXTxHB/IupTk2XJOAabm3d5 JRVuCF+MhmsNgyAv6hwwH2x01KHkn3Ck5o2EaP7ggtI10SSqyucec2QujSyUfYVWoKao 3Y6/3JpT7qoPp8tEqjQ3KW+l9AVjtHhSADIpCzAdkkOt5qiu9e5mM6CWZqnC4Ia+78Lo gaudxCe6d4U95T9LVZmWzkAczrBIR2d82KuHJQUbttZrXXjTim4uSxRFHjRAYBFUkvfW GYV1eZZnFl8Dbt9MnqE5U0fYlCWiefR2+6qvl84ZGY8xtd5JjlXKLl0LrIn61QhInEZT ZMkA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=virtuozzo.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g67-v6si3814217plb.163.2018.11.08.01.06.19; Thu, 08 Nov 2018 01:06:34 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=virtuozzo.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727197AbeKHSkP (ORCPT + 99 others); Thu, 8 Nov 2018 13:40:15 -0500 Received: from relay.sw.ru ([185.231.240.75]:36794 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726642AbeKHSkP (ORCPT ); Thu, 8 Nov 2018 13:40:15 -0500 Received: from [172.16.25.169] (helo=localhost.localdomain) by relay.sw.ru with esmtp (Exim 4.90_1) (envelope-from ) id 1gKgFy-00062m-Cx; Thu, 08 Nov 2018 12:05:42 +0300 Subject: [PATCH v2 5/5] fuse: Verify userspace asks to requeue interrupt that we really sent From: Kirill Tkhai To: miklos@szeredi.hu, ktkhai@virtuozzo.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Thu, 08 Nov 2018 12:05:42 +0300 Message-ID: <154166794230.10655.6677489856107857328.stgit@localhost.localdomain> In-Reply-To: <154166765576.10655.15178401490817622677.stgit@localhost.localdomain> References: <154166765576.10655.15178401490817622677.stgit@localhost.localdomain> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When queue_interrupt() is called from fuse_dev_do_write(), it came from userspace directly. Userspace may pass any request id, even the request's we have not interrupted (or even background's request). This patch adds sanity check to make kernel safe against that. v2: Keep in mind FR_INTERRUPTED is visible under fiq->waitq.lock in requeuer. Signed-off-by: Kirill Tkhai --- fs/fuse/dev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 7684fb7dc680..403a2ebad468 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -475,9 +475,15 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) fuse_put_request(fc, req); } -static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) +static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) { spin_lock(&fiq->waitq.lock); + /* Check for we've sent request to interrupt this req */ + if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) { + spin_unlock(&fiq->waitq.lock); + return -EINVAL; + } + if (list_empty(&req->intr_entry)) { list_add_tail(&req->intr_entry, &fiq->interrupts); /* @@ -488,12 +494,13 @@ static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) if (test_bit(FR_FINISHED, &req->flags)) { list_del_init(&req->intr_entry); spin_unlock(&fiq->waitq.lock); - return; + return 0; } wake_up_locked(&fiq->waitq); kill_fasync(&fiq->fasync, SIGIO, POLL_IN); } spin_unlock(&fiq->waitq.lock); + return 0; } static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) @@ -1951,8 +1958,9 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, nbytes = -EINVAL; else if (oh.error == -ENOSYS) fc->no_interrupt = 1; - else if (oh.error == -EAGAIN) - queue_interrupt(&fc->iq, req); + else if (oh.error == -EAGAIN && + queue_interrupt(&fc->iq, req) < 0) + nbytes = -EINVAL; fuse_put_request(fc, req); fuse_copy_finish(cs);