xfs
[Top] [All Lists]

[PATCH v7 1/9] dax: fix NULL pointer dereference in __dax_dbg()

To: linux-kernel@xxxxxxxxxxxxxxx
Subject: [PATCH v7 1/9] dax: fix NULL pointer dereference in __dax_dbg()
From: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
Date: Wed, 6 Jan 2016 11:00:55 -0700
Cc: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>, "H. Peter Anvin" <hpa@xxxxxxxxx>, "J. Bruce Fields" <bfields@xxxxxxxxxxxx>, "Theodore Ts'o" <tytso@xxxxxxx>, Alexander Viro <viro@xxxxxxxxxxxxxxxxxx>, Andreas Dilger <adilger.kernel@xxxxxxxxx>, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>, Dan Williams <dan.j.williams@xxxxxxxxx>, Dave Chinner <david@xxxxxxxxxxxxx>, Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>, Ingo Molnar <mingo@xxxxxxxxxx>, Jan Kara <jack@xxxxxxxx>, Jeff Layton <jlayton@xxxxxxxxxxxxxxx>, Matthew Wilcox <matthew.r.wilcox@xxxxxxxxx>, Matthew Wilcox <willy@xxxxxxxxxxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, linux-ext4@xxxxxxxxxxxxxxx, linux-fsdevel@xxxxxxxxxxxxxxx, linux-mm@xxxxxxxxx, linux-nvdimm@xxxxxxxxxxxx, x86@xxxxxxxxxx, xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1452103263-1592-1-git-send-email-ross.zwisler@xxxxxxxxxxxxxxx>
References: <1452103263-1592-1-git-send-email-ross.zwisler@xxxxxxxxxxxxxxx>
__dax_dbg() currently assumes that bh->b_bdev is non-NULL, passing it into
bdevname() where is is dereferenced.  This assumption isn't always true -
when called for reads of holes, ext4_dax_mmap_get_block() returns a buffer
head where bh->b_bdev is never set.  I hit this BUG while testing the DAX
PMD fault path.

Instead, verify that we have a valid bh->b_bdev, else just say "unknown"
for the block device.

Signed-off-by: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
---
 fs/dax.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/dax.c b/fs/dax.c
index 7af8797..03cc4a3 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -563,7 +563,12 @@ static void __dax_dbg(struct buffer_head *bh, unsigned 
long address,
 {
        if (bh) {
                char bname[BDEVNAME_SIZE];
-               bdevname(bh->b_bdev, bname);
+
+               if (bh->b_bdev)
+                       bdevname(bh->b_bdev, bname);
+               else
+                       snprintf(bname, BDEVNAME_SIZE, "unknown");
+
                pr_debug("%s: %s addr: %lx dev %s state %lx start %lld "
                        "length %zd fallback: %s\n", fn, current->comm,
                        address, bname, bh->b_state, (u64)bh->b_blocknr,
-- 
2.5.0

<Prev in Thread] Current Thread [Next in Thread>