mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 10:43:43 +00:00
scsi: ch: synchronize ch_probe() and ch_open()
The 'ch' device node is created before the configuration is being read in, which leads to a race window when ch_open() is called before that. To avoid any races we should be taking the device mutex during ch_readconfig() and ch_init_elem(), and also during ch_open(). That ensures ch_probe is finished before ch_open() completes. Link: https://lore.kernel.org/r/20200213153207.123357-3-hare@suse.de Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
66167283c2
commit
1c7ce4bcfb
@ -606,7 +606,10 @@ ch_open(struct inode *inode, struct file *file)
|
||||
mutex_unlock(&ch_mutex);
|
||||
return -ENXIO;
|
||||
}
|
||||
/* Synchronize with ch_probe() */
|
||||
mutex_lock(&ch->lock);
|
||||
file->private_data = ch;
|
||||
mutex_unlock(&ch->lock);
|
||||
mutex_unlock(&ch_mutex);
|
||||
return 0;
|
||||
}
|
||||
@ -949,6 +952,9 @@ static int ch_probe(struct device *dev)
|
||||
goto remove_idr;
|
||||
}
|
||||
|
||||
mutex_init(&ch->lock);
|
||||
kref_init(&ch->ref);
|
||||
ch->device = sd;
|
||||
class_dev = device_create(ch_sysfs_class, dev,
|
||||
MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
|
||||
"s%s", ch->name);
|
||||
@ -959,15 +965,16 @@ static int ch_probe(struct device *dev)
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
mutex_init(&ch->lock);
|
||||
kref_init(&ch->ref);
|
||||
ch->device = sd;
|
||||
mutex_lock(&ch->lock);
|
||||
ret = ch_readconfig(ch);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
mutex_unlock(&ch->lock);
|
||||
goto destroy_dev;
|
||||
}
|
||||
if (init)
|
||||
ch_init_elem(ch);
|
||||
|
||||
mutex_unlock(&ch->lock);
|
||||
dev_set_drvdata(dev, ch);
|
||||
sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user