>From 153918f99e45c685700e919a92384395dc18fd5d Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Thu, 2 Jan 2014 10:24:29 +0100 Subject: [PATCH] fix null pointer dereference in __blkdev_put We were hit by bug below: Dec 28 16:24:26 pserver1812 kernel: [979193.076399] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 Dec 28 16:24:26 pserver1812 kernel: [979193.076401] IP: [] __blkdev_put+0x17f/0x1d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076442] Pid: 56544, comm: multipath Tainted: G O 3.4.71-3-pserver #1 Supermicro BHQGE/BHQGE Dec 28 16:24:26 pserver1812 kernel: [979193.076445] RIP: 0010:[] [] __blkdev_put+0x17f/0x1d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076472] Call Trace: Dec 28 16:24:26 pserver1812 kernel: [979193.076477] [] ? fput+0xdd/0x270 Dec 28 16:24:26 pserver1812 kernel: [979193.076479] [] ? filp_close+0x5c/0x90 Dec 28 16:24:26 pserver1812 kernel: [979193.076481] [] ? sys_close+0x71/0xc0 Dec 28 16:24:26 pserver1812 kernel: [979193.076484] [] ? system_call_fastpath+0x16/0x1b Dec 28 16:24:26 pserver1812 kernel: [979193.076486] Code: 8b 5c 24 18 48 8b 6c 24 20 4c 8b 64 24 28 4c 8b 6c 24 30 4c 8b 74 24 38 4c 8b 7c 24 40 48 83 c4 48 c3 66 90 49 8b 86 48 03 00 00 <48> 8b 40 08 48 85 c0 0f 84 fc fe ff ff 44 89 e6 4c 89 f7 ff d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076500] RIP [] __blkdev_put+0x17f/0x1d0 Dec 28 16:24:26 pserver1812 kernel: [979193.076503] RSP Dec 28 16:24:26 pserver1812 kernel: [979193.076504] CR2: 0000000000000008 Dec 28 16:24:26 pserver1812 kernel: [979193.077599] ---[ end trace 23f39da823d257f9 ]--- Disamble code show null pointer happened in fops, fix by check before use it. Signed-off-by: Jack Wang --- fs/block_dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 319d9c7..d3c45b4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1483,8 +1483,9 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) &default_backing_dev_info); } if (bdev->bd_contains == bdev) { - if (disk->fops->release) - ret = disk->fops->release(disk, mode); + if (disk->fops) + if (disk->fops->release) + ret = disk->fops->release(disk, mode); } if (!bdev->bd_openers) { struct module *owner = disk->fops->owner; -- 1.8.4