Re: [PATCH v7 16/19] s390/dasd: Detect ESE volumes from the on-disk format label
[email protected] Sat, 01 Aug 2026 18:39:02 +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: New issues: - [Medium] The in-memory ESE format label cache (`ese_label_valid`) is not invalidated when the on-disk label is overwritten or erased without a new label being explicitly written. - [Medium] Lockless read and non-atomic update of the `ese_label` cache causes data races and potential torn reads. Pre-existing issues: - [Critical] Heap buffer overflow in `dasd_eckd_build_format()` when formatting multiple tracks with intensity 0x01. - [High] Pre-existing NULL pointer dereference in `dasd_release_space()` for devices without an `is_ese` discipline function. -- --- Patch [16]: [PATCH v7 16/19] s390/dasd: Detect ESE volumes from the on-disk format label --- commit ac9e4583836d81406ee7f0dc251d245f5892a7de Author: Stefan Haberland <[email protected]> Subject: s390/dasd: Detect ESE volumes from the on-disk format label Read the format label from track 0 record 4 at device bring-up and cache it. When a valid label is present, is_ese() is derived from it instead of the hardware volume field. The cache is refreshed after a format so is_ese() stays coherent without an offline/online cycle. > diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c > index 7a27dc08fb961..68736f9efcaf2 100644 > --- a/drivers/s390/block/dasd_eckd.c > +++ b/drivers/s390/block/dasd_eckd.c [ ... ] > @@ -1676,7 +1676,8 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device) > +static int dasd_eckd_is_ese(struct dasd_device *device) > +{ > + struct dasd_eckd_private *private = device->private; > + > + /* sysfs may read this during set_online before private is allocated */ > + if (!private) > + return 0; > + > + if (private->ese_label_valid) > + return !!(private->ese_label.flags & DASD_ESE_LABEL_F_ESE); [Severity: Medium] Does this code allow a data race when reading the label flags? Looking at dasd_eckd_is_ese() and dasd_eckd_on_demand_format(), they read private->ese_label_valid and private->ese_label.flags without locks or memory barriers. If a concurrent update happens in dasd_eckd_fill_format_label() during a format operation, could this lead to a torn read and transiently incorrect sysfs output? > + > + return dasd_eckd_ese_capable(device); > +} [ ... ] > @@ -2733,7 +2847,12 @@ static void dasd_eckd_fill_format_label(struct dasd_device *device, void *data, > label->format_tod = get_tod_clock(); > strscpy(label->kernel_version, init_utsname()->release, > sizeof(label->kernel_version)); > + > + /* > + * Populate the cache directly from the bytes just computed instead of > + * synchronously reading them back from disk after the write lands. > + */ > + private->ese_label = *label; > + private->ese_label_valid = true; [Severity: Medium] Does this code update the 512-byte label cache safely? Since this struct copy is not atomic, could concurrent readers in dasd_eckd_is_ese() observe an inconsistent state? > } [ ... ] > @@ -3227,23 +3353,35 @@ static int dasd_eckd_format_device(struct dasd_device *base, > - if (fdata->start_unit == 0) > - private->ese_format_quick = 0; > + private->ese_format_quick = 0; > + > + /* > + * A full format returns the device to a fully sparse state and has just > + * committed a fresh label; restart the heuristic from ft1 on the now > + * current is_ese state, without an offline cycle. > + */ > + dasd_ft_bias_apply(base); > + > return rc; > } [Severity: Medium] Does this code properly invalidate the label cache when the label is erased? In dasd_eckd_format_device(), the success path clears ese_format_quick but does not clear ese_label_valid when track 0 is formatted with a non-CDL layout (intensity 0) where no label is explicitly written. Similarly, space release successfully unallocates all tracks (erasing track 0) in dasd_eckd_release_space_full() but fails to invalidate the label cache. Could this cause the driver to retain a stale label cache and incorrectly apply ESE-specific performance heuristics to non-ESE devices? Additional observations about related pre-existing code: [Severity: High] This is a pre-existing issue, but does dasd_release_space() in drivers/s390/block/dasd_ioctl.c have a NULL pointer dereference? If a device uses a discipline that does not implement the is_ese callback, such as FBA: if (!device->discipline->is_ese && !device->discipline->is_ese(device)) Could this logic flaw trigger a panic when a user issues the release space ioctl, since it uses a logical AND instead of OR? [Severity: Critical] This is a pre-existing issue, but does dasd_eckd_build_format() in drivers/s390/block/dasd_eckd.c have a heap buffer overflow? When formatting multiple tracks with intensity 0x01, the memory is allocated for the CCW chain using: cplength = 2 + rpt * nr_tracks; However, the generation loop consumes an extra CCW per track for record zero, meaning it consumes 1 + rpt CCWs per track. If a user requests a format spanning multiple tracks, could this deficit cause an out-of-bounds write into the dasd_alloc_chunk heap memory pool? -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=16