mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 22:52:35 +02:00
dm table: reject devices without request fns
commitf4808ca99aupstream. This patch adds a check that a block device has a request function defined before it is used. Otherwise, misconfiguration can cause an oops. Because we are allowing devices with zero size e.g. an offline multipath device as in commit2cd54d9bed("dm: allow offline devices") there needs to be an additional check to ensure devices are initialised. Some block devices, like a loop device without a backing file, exist but have no request function. Reproducer is trivial: dm-mirror on unbound loop device (no backing file on loop devices) dmsetup create x --table "0 8 mirror core 2 8 sync 2 /dev/loop0 0 /dev/loop1 0" and mirror resync will immediatelly cause OOps. BUG: unable to handle kernel NULL pointer dereference at (null) ? generic_make_request+0x2bd/0x590 ? kmem_cache_alloc+0xad/0x190 submit_bio+0x53/0xe0 ? bio_add_page+0x3b/0x50 dispatch_io+0x1ca/0x210 [dm_mod] ? read_callback+0x0/0xd0 [dm_mirror] dm_io+0xbb/0x290 [dm_mod] do_mirror+0x1e0/0x748 [dm_mirror] Signed-off-by: Milan Broz <mbroz@redhat.com> Reported-by: Zdenek Kabelac <zkabelac@redhat.com> Acked-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
af73c7b853
commit
a4401a63a8
|
|
@ -348,6 +348,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
|
|||
static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
|
||||
sector_t start, sector_t len, void *data)
|
||||
{
|
||||
struct request_queue *q;
|
||||
struct queue_limits *limits = data;
|
||||
struct block_device *bdev = dev->bdev;
|
||||
sector_t dev_size =
|
||||
|
|
@ -356,6 +357,22 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
|
|||
limits->logical_block_size >> SECTOR_SHIFT;
|
||||
char b[BDEVNAME_SIZE];
|
||||
|
||||
/*
|
||||
* Some devices exist without request functions,
|
||||
* such as loop devices not yet bound to backing files.
|
||||
* Forbid the use of such devices.
|
||||
*/
|
||||
q = bdev_get_queue(bdev);
|
||||
if (!q || !q->make_request_fn) {
|
||||
DMWARN("%s: %s is not yet initialised: "
|
||||
"start=%llu, len=%llu, dev_size=%llu",
|
||||
dm_device_name(ti->table->md), bdevname(bdev, b),
|
||||
(unsigned long long)start,
|
||||
(unsigned long long)len,
|
||||
(unsigned long long)dev_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!dev_size)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user