Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3326675imu; Sun, 11 Nov 2018 12:26:46 -0800 (PST) X-Google-Smtp-Source: AJdET5fbzdO5Vo68qivKDLcKXGB/ZGIQR5GY+QdtdMFWdsnzObT85f/lCJ2LTu2vS73uZ58VwFja X-Received: by 2002:a63:1a0c:: with SMTP id a12mr14800521pga.157.1541968006581; Sun, 11 Nov 2018 12:26:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541968006; cv=none; d=google.com; s=arc-20160816; b=QJymUBGfYE4J3h3V2P1MPoBpCPC3e4CezsXbLucD4vh9OI2b/4flg2bkepa8VXX17W Nl5O7HZqOc07BEIoL1SlmeO6gsW01fiLLLycPTmd0c06UkyqOe+XfgA81Qq/DT6HYz7L Qos/O0xuaMZFgY/Gx9spOFu+K3AVnolZkIw5JCoJ7OHd1OPj7gMSoHxjXtvTfDo8bFTD hUBUhe+lSnjHgU3kAn0TAPJr5G8rnuhZRMRtCBjqB5AxSg0D5ebTM+yxCjmHWVHxeq/f RX8mRl7LjRJfj7ZXsOwUKhvLKYxFJg3FFE2/qD/Arucn//zPIGZ2Xc6FYWmMKhAD9kon 3jTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=XtlvOl9rspDsDjJUvFJQCq69T9BtPf8Wp8r82RHxaFY=; b=pfxyJw2boFPAM/V8FG5SlsZE+fSESFqFAeHMXMqurU6wCskYcT1TVRUP9RmDnykUi1 6r/7gs8qC3bfVq2JDoPrJvDpMmwQbBd+sigJgF1aBYiYrXmkzdVHmSR2Esu2FC9qHNzA suDtF3sK3ukA/RqT/9RX8oHdPCClCmOBKgxvOGkHSu2wYapU+QNDbP1UBHbQHBxF7Xuf Fg7kasG8QNwFCQx1iYwuII6zZSsl/N+6z7C2NhABVOjV5459Do/ReoTGh9lWArCNJBei qTWVqegRLf45ZHqtJ6Dv4e9q0bkouapKi579IDca5Aw+G62L5w5hbJo+yN+gBec6jRp7 4WDA== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y35-v6si14024349pgl.14.2018.11.11.12.26.31; Sun, 11 Nov 2018 12:26:46 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730682AbeKLFs2 (ORCPT + 99 others); Mon, 12 Nov 2018 00:48:28 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:50856 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730628AbeKLFs1 (ORCPT ); Mon, 12 Nov 2018 00:48:27 -0500 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gLvsl-0000l4-Pv; Sun, 11 Nov 2018 19:58:56 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gLvsY-0001mB-4A; Sun, 11 Nov 2018 19:58:42 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "David Howells" , "Anthony DeRobertis" , "Lei Xue" , "Kiran Kumar Modukuri" , "Vegard Nossum" , "NeilBrown" , "Daniel Axtens" Date: Sun, 11 Nov 2018 19:49:05 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 289/366] cachefiles: Fix refcounting bug in backing-file read monitoring In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.61-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Kiran Kumar Modukuri commit 934140ab028713a61de8bca58c05332416d037d1 upstream. cachefiles_read_waiter() has the right to access a 'monitor' object by virtue of being called under the waitqueue lock for one of the pages in its purview. However, it has no ref on that monitor object or on the associated operation. What it is allowed to do is to move the monitor object to the operation's to_do list, but once it drops the work_lock, it's actually no longer permitted to access that object. However, it is trying to enqueue the retrieval operation for processing - but it can only do this via a pointer in the monitor object, something it shouldn't be doing. If it doesn't enqueue the operation, the operation may not get processed. If the order is flipped so that the enqueue is first, then it's possible for the work processor to look at the to_do list before the monitor is enqueued upon it. Fix this by getting a ref on the operation so that we can trust that it will still be there once we've added the monitor to the to_do list and dropped the work_lock. The op can then be enqueued after the lock is dropped. The bug can manifest in one of a couple of ways. The first manifestation looks like: FS-Cache: FS-Cache: Assertion failed FS-Cache: 6 == 5 is false ------------[ cut here ]------------ kernel BUG at fs/fscache/operation.c:494! RIP: 0010:fscache_put_operation+0x1e3/0x1f0 ... fscache_op_work_func+0x26/0x50 process_one_work+0x131/0x290 worker_thread+0x45/0x360 kthread+0xf8/0x130 ? create_worker+0x190/0x190 ? kthread_cancel_work_sync+0x10/0x10 ret_from_fork+0x1f/0x30 This is due to the operation being in the DEAD state (6) rather than INITIALISED, COMPLETE or CANCELLED (5) because it's already passed through fscache_put_operation(). The bug can also manifest like the following: kernel BUG at fs/fscache/operation.c:69! ... [exception RIP: fscache_enqueue_operation+246] ... #7 [ffff883fff083c10] fscache_enqueue_operation at ffffffffa0b793c6 #8 [ffff883fff083c28] cachefiles_read_waiter at ffffffffa0b15a48 #9 [ffff883fff083c48] __wake_up_common at ffffffff810af028 I'm not entirely certain as to which is line 69 in Lei's kernel, so I'm not entirely clear which assertion failed. Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") Reported-by: Lei Xue Reported-by: Vegard Nossum Reported-by: Anthony DeRobertis Reported-by: NeilBrown Reported-by: Daniel Axtens Reported-by: Kiran Kumar Modukuri Signed-off-by: David Howells Reviewed-by: Daniel Axtens Signed-off-by: Ben Hutchings --- fs/cachefiles/rdwr.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -27,6 +27,7 @@ static int cachefiles_read_waiter(wait_q struct cachefiles_one_read *monitor = container_of(wait, struct cachefiles_one_read, monitor); struct cachefiles_object *object; + struct fscache_retrieval *op = monitor->op; struct wait_bit_key *key = _key; struct page *page = wait->private; @@ -51,16 +52,22 @@ static int cachefiles_read_waiter(wait_q list_del(&wait->task_list); /* move onto the action list and queue for FS-Cache thread pool */ - ASSERT(monitor->op); + ASSERT(op); - object = container_of(monitor->op->op.object, - struct cachefiles_object, fscache); + /* We need to temporarily bump the usage count as we don't own a ref + * here otherwise cachefiles_read_copier() may free the op between the + * monitor being enqueued on the op->to_do list and the op getting + * enqueued on the work queue. + */ + fscache_get_retrieval(op); + object = container_of(op->op.object, struct cachefiles_object, fscache); spin_lock(&object->work_lock); - list_add_tail(&monitor->op_link, &monitor->op->to_do); + list_add_tail(&monitor->op_link, &op->to_do); spin_unlock(&object->work_lock); - fscache_enqueue_retrieval(monitor->op); + fscache_enqueue_retrieval(op); + fscache_put_retrieval(op); return 0; }