From patchwork Mon Dec 7 18:05:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suzuki K Poulose X-Patchwork-Id: 7788591 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0F863BEEE1 for ; Mon, 7 Dec 2015 18:05:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 284E0203C0 for ; Mon, 7 Dec 2015 18:05:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2C9A320328 for ; Mon, 7 Dec 2015 18:05:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932385AbbLGSFS (ORCPT ); Mon, 7 Dec 2015 13:05:18 -0500 Received: from eu-smtp-delivery-143.mimecast.com ([207.82.80.143]:27584 "EHLO eu-smtp-delivery-143.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932394AbbLGSFQ (ORCPT ); Mon, 7 Dec 2015 13:05:16 -0500 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-18-riKxBnlAQRadI8OQZ_PesQ-1; Mon, 07 Dec 2015 18:05:13 +0000 Received: from e106634-lin.cambridge.arm.com ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 7 Dec 2015 18:05:12 +0000 From: "Suzuki K. Poulose" To: viro@zeniv.linux.org.uk Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, marc.zyngier@arm.com, torvalds@linux-foundation.org, "Suzuki K. Poulose" , Tejun Heo , stable@vger.kernel.org Subject: [PATCH] blkdev: Fix blkdev_open to release the bdev on error Date: Mon, 7 Dec 2015 18:05:03 +0000 Message-Id: <1449511503-7543-1-git-send-email-suzuki.poulose@arm.com> X-Mailer: git-send-email 1.7.9.5 X-OriginalArrivalTime: 07 Dec 2015 18:05:12.0818 (UTC) FILETIME=[D1700D20:01D13119] X-MC-Unique: riKxBnlAQRadI8OQZ_PesQ-1 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP blkdev_open() doesn't release the bdev, it attached to a given inode, if blkdev_get() fails (e.g, due to absence of a device). This can cause kernel crashes when the original filesystem tries to flush the data during evict_inode. This can be triggered easily with virtio-9p fs using the following simple steps. root@localhost:~# mknod disk b 9 1 root@localhost:~# cat disk Unable to handle kernel NULL pointer dereference at virtual address 00000214 pgd = bea40000 [00000214] *pgd=be9eb831, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1094 Comm: cat Not tainted 4.3.0 #3 Hardware name: Generic DT based system task: bf186600 ti: be822000 task.ti: be822000 PC is at blk_get_backing_dev_info+0x4/0x10 LR is at __filemap_fdatawrite_range+0x88/0x94 pc : [<80317e00>] lr : [<801995d4>] psr: 60010013 sp : be823db0 ip : 00000000 fp : 00000024 r10: fffffffa r9 : be86a240 r8 : bec87e58 r7 : 00000001 r6 : 80615640 r5 : 7fffffff r4 : bec03354 r3 : 00000000 r2 : bf006c00 r1 : 7fffffff r0 : bec03200 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5383d Table: bea4006a DAC: 00000051 Process cat (pid: 1094, stack limit = 0xbe822210) [... stack contents trimmed ...] [<80317e00>] (blk_get_backing_dev_info) from [<801995d4>] (__filemap_fdatawrite_range+0x88/0x94) [<801995d4>] (__filemap_fdatawrite_range) from [<80199608>] (filemap_fdatawrite+0x28/0x30) [<80199608>] (filemap_fdatawrite) from [<802fa830>] (v9fs_evict_inode+0x20/0x3c) [<802fa830>] (v9fs_evict_inode) from [<801ef4fc>] (evict+0xb0/0x188) [<801ef4fc>] (evict) from [<801eb998>] (__dentry_kill+0x1ec/0x250) [<801eb998>] (__dentry_kill) from [<801ec2d8>] (dput+0x188/0x28c) [<801ec2d8>] (dput) from [<801e0858>] (path_put+0x10/0x1c) [<801e0858>] (path_put) from [<801e08a0>] (terminate_walk+0x3c/0x98) [<801e08a0>] (terminate_walk) from [<801e3d54>] (path_openat+0x1ec/0xeac) [<801e3d54>] (path_openat) from [<801e56c8>] (do_filp_open+0x60/0xb4) [<801e56c8>] (do_filp_open) from [<801d7850>] (do_sys_open+0x124/0x1d0) [<801d7850>] (do_sys_open) from [<80107340>] (ret_fast_syscall+0x0/0x3c) Code: 806d3ca0 80941b7c 807175d8 e590305c (e5930214) ---[ end trace b61b160a3217ae29 ]--- Fixes: e525fd89d380c4a94c0d63913a1dd1a593ed25e7 Cc: Tejun Heo Cc: stable@vger.kernel.org Cc: Al Viro Signed-off-by: Suzuki K. Poulose --- fs/block_dev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index c25639e..7d7f322 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1484,6 +1484,7 @@ EXPORT_SYMBOL(blkdev_get_by_dev); static int blkdev_open(struct inode * inode, struct file * filp) { + int rc; struct block_device *bdev; /* @@ -1507,7 +1508,11 @@ static int blkdev_open(struct inode * inode, struct file * filp) filp->f_mapping = bdev->bd_inode->i_mapping; - return blkdev_get(bdev, filp->f_mode, filp); + rc = blkdev_get(bdev, filp->f_mode, filp); + if (rc) + bd_forget(inode); + + return rc; } static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)