Re: [PATCH v5 02/17] s390/dasd: Guard sysfs discipline callbacks against unallocated private data

[email protected] Fri, 31 Jul 2026 15:59:37 +0000
Newsgroups org.kernel.vger.linux-s390
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [Critical] The patch fails to fully resolve the initialization race for the `host_access_count` sysfs attribute, resulting in a NULL pointer dereference. While it adds a `!private` check to `dasd_eckd_query_host_access()`, it overlooks that `private->lcu` remains NULL until populated later by `dasd_alias_make_device_known_to_lcu()`. An unprivileged sysfs read during this window will bypass the `!private` check and unconditionally dereference `private->lcu->pav`, causing a kernel panic.
- [Critical] The `if (!private)` checks added by the patch fail to protect against concurrent freeing of `device->private` during device initialization errors, leading to a Use-After-Free and memory corruption. If `dasd_eckd_check_characteristics` fails, its error path frees `device->private`. A concurrent unprivileged sysfs read can fetch the non-NULL pointer just before it is freed, bypass the check, and subsequently dereference or write to the freed memory.
- [High] Missing NULL pointer checks in `dasd_copy_pair_store` and `dasd_eckd_pprc_enabled` allow a kernel panic when configuring copy pairs via sysfs during device initialization. The sysfs store handler `dasd_copy_pair_store` does not verify if `device->discipline` is allocated before dereferencing `device->discipline->pprc_enabled`. Furthermore, if `device->discipline` is assigned but `device->private` is not yet allocated, `dasd_eckd_pprc_enabled` unconditionally dereferences `device->private`, resulting in a kernel panic.
- [High] Missing NULL pointer check for `device->private` in `dasd_eckd_read_fc_security()`, leading to a kernel panic triggered by asynchronous path events during initialization. If a hardware path event occurs after `device->discipline` is assigned but before `device->private` is allocated, `do_pe_handler_work()` executes and calls `dasd_eckd_read_fc_security()`, which unconditionally dereferences `private`.
--

--- Patch [2]: [PATCH v5 02/17] s390/dasd: Guard sysfs discipline callbacks against unallocated private data ---
commit d022f6e90af16afe7ae1766d9ba490832f14cca6
Author: Stefan Haberland <[email protected]>

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.

> diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
> index 74fe73b5738ab..a820d68122d93 100644
> --- a/drivers/s390/block/dasd_eckd.c
> +++ b/drivers/s390/block/dasd_eckd.c
[ ... ]
> @@ -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;
> +

[Severity: Critical]
This is a pre-existing issue, but does this check protect against concurrent
freeing of device->private during device initialization errors?

If dasd_eckd_check_characteristics() fails, its error path frees
device->private without synchronization against concurrent lockless sysfs
readers:

    kfree(device->private);
    device->private = NULL;

Could a concurrent unprivileged sysfs read fetch the non-NULL pointer, pass
this check, and then perform a Use-After-Free when dasd_eckd_read_vol_info()
copies data into the freed private->vsq buffer?

>  	rc = dasd_eckd_read_vol_info(device);
[ ... ]
> @@ -5935,6 +5965,9 @@ 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)

[Severity: Critical]
This is a pre-existing issue, but could this still lead to a NULL pointer
dereference?

While this check ensures private is not NULL, private->lcu can remain NULL
until it is populated later by dasd_alias_make_device_known_to_lcu().

If an unprivileged sysfs read triggers dasd_eckd_host_access_count() which
calls dasd_eckd_query_host_access() during this window, wouldn't it bypass
the !private check and unconditionally dereference private->lcu->pav?

>  		return -EOPNOTSUPP;

[Severity: High]
This is a pre-existing issue, but I noticed a couple of other places that
might need similar NULL pointer checks.

In dasd_copy_pair_store() in drivers/s390/block/dasd_devmap.c, could
device->discipline be dereferenced while it is NULL when a user writes to
the copy_pair sysfs attribute during device initialization?

    if (device->discipline->pprc_enabled) {

Additionally, if device->discipline is set but device->private is not yet
allocated, could dasd_eckd_pprc_enabled() in drivers/s390/block/dasd_eckd.c
unconditionally dereference device->private?

    return private->rdc_data.facilities.PPRC_enabled;

[Severity: High]
This is also a pre-existing issue, but is a NULL check for device->private
needed in dasd_eckd_read_fc_security() as well?

If a hardware path event occurs after device->discipline is assigned but
before device->private is allocated, do_pe_handler_work() executes and calls
dasd_eckd_read_fc_security().

Could this unconditionally dereference private?

    rc = chsc_scud(private->uid.ssid, (u64 *)esm, &esm_valid);

-- 
Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=2