mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
s390/dasd: Guard sysfs discipline callbacks against unallocated private data
Several sysfs show/store handlers call a discipline callback that
dereferences device->private, either directly or through the
DASD_DEFINE_ATTR() macro. During dasd_generic_set_online() the discipline
is assigned before check_device() allocates device->private, so an
unprivileged read of one of these world-readable attributes in that window
dereferences a NULL pointer and panics.
Guard the dereference inside each callback that actually touches
device->private.
Fixes: c729696bcf ("s390/dasd: Recognise data for ESE volumes")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://patch.msgid.link/20260805111612.1285190-4-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
6fb5ba2e7e
commit
2a1780f9fc
|
|
@ -1491,6 +1491,8 @@ static void dasd_eckd_reset_path(struct dasd_device *device, __u8 pm)
|
|||
struct dasd_eckd_private *private = device->private;
|
||||
unsigned long flags;
|
||||
|
||||
if (!private)
|
||||
return;
|
||||
if (!private->fcx_max_data)
|
||||
private->fcx_max_data = get_fcx_max_data(device);
|
||||
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
|
||||
|
|
@ -1646,6 +1648,9 @@ static int dasd_eckd_is_ese(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->vsq.vol_info.ese;
|
||||
}
|
||||
|
||||
|
|
@ -1653,6 +1658,9 @@ static int dasd_eckd_ext_pool_id(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->vsq.extent_pool_id;
|
||||
}
|
||||
|
||||
|
|
@ -1666,6 +1674,9 @@ static int dasd_eckd_space_configured(struct dasd_device *device)
|
|||
struct dasd_eckd_private *private = device->private;
|
||||
int rc;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
rc = dasd_eckd_read_vol_info(device);
|
||||
|
||||
return rc ? : private->vsq.space_configured;
|
||||
|
|
@ -1680,6 +1691,9 @@ static int dasd_eckd_space_allocated(struct dasd_device *device)
|
|||
struct dasd_eckd_private *private = device->private;
|
||||
int rc;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
rc = dasd_eckd_read_vol_info(device);
|
||||
|
||||
return rc ? : private->vsq.space_allocated;
|
||||
|
|
@ -1689,6 +1703,9 @@ static int dasd_eckd_logical_capacity(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->vsq.logical_capacity;
|
||||
}
|
||||
|
||||
|
|
@ -1831,7 +1848,11 @@ static int dasd_eckd_read_ext_pool_info(struct dasd_device *device)
|
|||
static int dasd_eckd_ext_size(struct dasd_device *device)
|
||||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
struct dasd_ext_pool_sum eps = private->eps;
|
||||
struct dasd_ext_pool_sum eps;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
eps = private->eps;
|
||||
|
||||
if (!eps.flags.extent_size_valid)
|
||||
return 0;
|
||||
|
|
@ -1847,6 +1868,9 @@ static int dasd_eckd_ext_pool_warn_thrshld(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->eps.warn_thrshld;
|
||||
}
|
||||
|
||||
|
|
@ -1854,6 +1878,9 @@ static int dasd_eckd_ext_pool_cap_at_warnlevel(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->eps.flags.capacity_at_warnlevel;
|
||||
}
|
||||
|
||||
|
|
@ -1864,6 +1891,9 @@ static int dasd_eckd_ext_pool_oos(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->eps.flags.pool_oos;
|
||||
}
|
||||
|
||||
|
|
@ -5935,8 +5965,11 @@ static int dasd_eckd_query_host_access(struct dasd_device *device,
|
|||
struct ccw1 *ccw;
|
||||
int rc;
|
||||
|
||||
if (!private)
|
||||
return -ENODEV;
|
||||
|
||||
/* not available for HYPER PAV alias devices */
|
||||
if (!device->block && private->lcu->pav == HYPER_PAV)
|
||||
if (!device->block && private->lcu && private->lcu->pav == HYPER_PAV)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* may not be supported by the storage server */
|
||||
|
|
@ -6801,6 +6834,9 @@ static int dasd_eckd_hpf_enabled(struct dasd_device *device)
|
|||
{
|
||||
struct dasd_eckd_private *private = device->private;
|
||||
|
||||
if (!private)
|
||||
return 0;
|
||||
|
||||
return private->fcx_max_data ? 1 : 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user