Commit ab01cffc authored by Jens Axboe's avatar Jens Axboe Committed by Greg Kroah-Hartman
Browse files

sr: get/drop reference to device in revalidate and check_events

[ Upstream commit 2d097c50 ]

We can't just use scsi_cd() to get the scsi_cd structure, we have
to grab a live reference to the device. For both callbacks, we're
not inside an open where we already hold a reference to the device.

This fixes device removal/addition under concurrent device access,
which otherwise could result in the below oops.

NULL pointer dereference at 0000000000000010
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP
Modules linked in:
sr 12:0:0:0: [sr2] scsi-1 drive
 scsi_debug crc_t10dif crct10dif_generic crct10dif_common nvme nvme_core sb_edac xl
sr 12:0:0:0: Attached scsi CD-ROM sr2
 sr_mod cdrom btrfs xor zstd_decompress zstd_compress xxhash lzo_compress zlib_defc
sr 12:0:0:0: Attached scsi generic sg7 type 5
 igb ahci libahci i2c_algo_bit libata dca [last unloaded: crc_t10dif]
CPU: 43 PID: 4629 Comm: systemd-udevd Not tainted 4.16.0+ #650
Hardware name: Dell Inc. PowerEdge T630/0NT78X, BIOS 2.3...
parent c8199e33
Showing with 15 additions and 4 deletions
+15 -4
......@@ -587,18 +587,28 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
static unsigned int sr_block_check_events(struct gendisk *disk,
unsigned int clearing)
{
struct scsi_cd *cd = scsi_cd(disk);
unsigned int ret = 0;
struct scsi_cd *cd;
if (atomic_read(&cd->device->disk_events_disable_depth))
cd = scsi_cd_get(disk);
if (!cd)
return 0;
return cdrom_check_events(&cd->cdi, clearing);
if (!atomic_read(&cd->device->disk_events_disable_depth))
ret = cdrom_check_events(&cd->cdi, clearing);
scsi_cd_put(cd);
return ret;
}
static int sr_block_revalidate_disk(struct gendisk *disk)
{
struct scsi_cd *cd = scsi_cd(disk);
struct scsi_sense_hdr sshdr;
struct scsi_cd *cd;
cd = scsi_cd_get(disk);
if (!cd)
return -ENXIO;
/* if the unit is not ready, nothing more to do */
if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
......@@ -607,6 +617,7 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
sr_cd_check(&cd->cdi);
get_sectorsize(cd);
out:
scsi_cd_put(cd);
return 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment