qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] block/file-posix: fix wps checking in raw_co_prw


From: Damien Le Moal
Subject: Re: [PATCH v2] block/file-posix: fix wps checking in raw_co_prw
Date: Thu, 8 Jun 2023 10:29:08 +0900
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.0

On 6/8/23 03:57, Sam Li wrote:
> If the write operation fails and the wps is NULL, then accessing it will
> lead to data corruption.
> 
> Solving the issue by adding a nullptr checking in get_zones_wp() where
> the wps is used.
> 
> This issue is found by Peter Maydell using the Coverity Tool (CID
> 1512459).
> 
> Signed-off-by: Sam Li <faithilikerun@gmail.com>
> ---
>  block/file-posix.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index ac1ed54811..4a6c71c7f5 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2523,7 +2523,7 @@ out:
>              }
>          }
>      } else {
> -        if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
> +        if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND) && wps) {
>              update_zones_wp(bs, s->fd, 0, 1);

Nit: this could be:

        } else if (wps && type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {

However, both if & else side do something only if the above condition is true
and we only need to that for a zoned drive. So the entire code block could
really be simplified to be a lot more readable. Something like this (totally
untested, not even compiled):

#if defined(CONFIG_BLKZONED)
    if (bs->bl.zone_size && (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND))) {
        BlockZoneWps *wps = bs->wps;
        uint64_t *wp;

        if (!wps) {
            return ret;
        }

        if (ret) {
            /* write error: update the wp from the underlying device */
            update_zones_wp(bs, s->fd, 0, 1);
            goto unlock;
        }

        wp = &wps->wp[offset / bs->bl.zone_size];
        if (BDRV_ZT_IS_CONV(*wp)) {
            /* Conventional zones do not have a write pointer */
            goto unlock;
        }

        /* Return the written position for zone append */
        if (type & QEMU_AIO_ZONE_APPEND) {
            *s->offset = *wp;
            trace_zbd_zone_append_complete(bs,
                    *s->offset >> BDRV_SECTOR_BITS);
        }

        /* Advance the wp if needed */
        if (offset + bytes > *wp) {
            *wp = offset + bytes;
        }

unlock:
        qemu_co_mutex_unlock(&wps->colock);
    }
#endif

And making this entire block a helper function (e.g. advance_zone_wp()) would
further clean the code. But that should be done in another patch. Care to send 
one ?

-- 
Damien Le Moal
Western Digital Research




reply via email to

[Prev in Thread] Current Thread [Next in Thread]