mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 16:12:02 +00:00
s390/cio: fix out-of-bounds access on cio_ignore free
The channel-subsystem-driver scans for newly available devices whenever device-IDs are removed from the cio_ignore list using a command such as: echo free >/proc/cio_ignore Since an I/O device scan might interfer with running I/Os, commit172da89ed0
("s390/cio: avoid excessive path-verification requests") introduced an optimization to exclude online devices from the scan. The newly added check for online devices incorrectly assumes that an I/O-subchannel's drvdata points to a struct io_subchannel_private. For devices that are bound to a non-default I/O subchannel driver, such as the vfio_ccw driver, this results in an out-of-bounds read access during each scan. Fix this by changing the scan logic to rely on a driver-independent online indication. For this we can use struct subchannel->config.ena, which is the driver's requested subchannel-enabled state. Since I/Os can only be started on enabled subchannels, this matches the intent of the original optimization of not scanning devices where I/O might be running. Fixes:172da89ed0
("s390/cio: avoid excessive path-verification requests") Fixes:0c3812c347
("s390/cio: derive cdev information only for IO-subchannels") Cc: <stable@vger.kernel.org> # v5.15 Reported-by: Alexander Egorenkov <egorenar@linux.ibm.com> Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com> Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
8b1e6a3fb3
commit
1b60741127
@ -753,13 +753,9 @@ static int __unset_online(struct device *dev, void *data)
|
||||
{
|
||||
struct idset *set = data;
|
||||
struct subchannel *sch = to_subchannel(dev);
|
||||
struct ccw_device *cdev;
|
||||
|
||||
if (sch->st == SUBCHANNEL_TYPE_IO) {
|
||||
cdev = sch_get_cdev(sch);
|
||||
if (cdev && cdev->online)
|
||||
idset_sch_del(set, sch->schid);
|
||||
}
|
||||
if (sch->st == SUBCHANNEL_TYPE_IO && sch->config.ena)
|
||||
idset_sch_del(set, sch->schid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user