On Fri, 24 Jul 2026 11:24:13 +0200
Cédric Le Goater <[email protected]> wrote:

> When vfio_pci_load_rom() fails, vdev->rom is NULL but the memcpy
> still computes a source pointer from it, which is undefined behavior.
> Guard the access and return a 0xff pattern instead, which is what
> hardware returns for an absent ROM.
> 
> Signed-off-by: Cédric Le Goater <[email protected]>
> ---
>  hw/vfio/pci.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 
> a3147d28665abd29fd804bd08bdffc3c7440033c..16d4f70ea58c9e5b174dd57950df55dc2ab91f6f
>  100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -1176,8 +1176,13 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr 
> addr, unsigned size)
>          }
>      }
>  
> -    memcpy(&val, vdev->rom + addr,
> -           (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0);
> +    /* If ROM loading failed, return 0xff pattern */
> +    if (vdev->rom_read_failed) {
> +        memset(&val, 0xff, sizeof(val));
> +    } else {
> +        memcpy(&val, vdev->rom + addr,
> +               (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 
> 0);
> +    }
>  
>      switch (size) {
>      case 1:

I thought we guaranteed that when (vdev->rom == NULL) that
(vdev->rom_size == 0), thus we end up with a harmless zero-sized memcpy
here.  Also val is pre-initialized to ~0 so the memset() is redundant.

Does this actually change any behavior or is it only meant to sanitize
the undefined (NULL + addr) pointer that's never dereferenced?  If the
latter, I'd drop the memset and note it explicitly as a sanitization,
not a fix.  Thanks,

Alex

Reply via email to