[PATCH] hw/misc/ivshmem-pci: Improve error handling

Peter Maydell posted 1 patch 5 months, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250711145012.1521936-1-peter.maydell@linaro.org
hw/misc/ivshmem-pci.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
[PATCH] hw/misc/ivshmem-pci: Improve error handling
Posted by Peter Maydell 5 months, 1 week ago
Coverity points out that the ivshmem-pci code has some error handling
cases where it incorrectly tries to use an invalid filedescriptor.
These generally happen because ivshmem_recv_msg() calls
qemu_chr_fe_get_msgfd(), which might return -1, but the code in
process_msg() generally assumes that the file descriptor was provided
when it was supposed to be. In particular:
 * the error case in process_msg() only needs to close the fd
   if one was provided
 * process_msg_shmem() should fail if no fd was provided

Coverity: CID 1508726
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Disclaimer: tested only with "make check"
---
 hw/misc/ivshmem-pci.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c
index 5a10bca633d..d47ae739d61 100644
--- a/hw/misc/ivshmem-pci.c
+++ b/hw/misc/ivshmem-pci.c
@@ -479,6 +479,11 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
     struct stat buf;
     size_t size;
 
+    if (fd < 0) {
+        error_setg(errp, "server didn't provide fd with shared memory message");
+        return;
+    }
+
     if (s->ivshmem_bar2) {
         error_setg(errp, "server sent unexpected shared memory message");
         close(fd);
@@ -553,7 +558,9 @@ static void process_msg(IVShmemState *s, int64_t msg, int fd, Error **errp)
 
     if (msg < -1 || msg > IVSHMEM_MAX_PEERS) {
         error_setg(errp, "server sent invalid message %" PRId64, msg);
-        close(fd);
+        if (fd >= 0) {
+            close(fd);
+        }
         return;
     }
 
-- 
2.43.0
Re: [PATCH] hw/misc/ivshmem-pci: Improve error handling
Posted by Markus Armbruster 5 months, 1 week ago
Peter Maydell <peter.maydell@linaro.org> writes:

> Coverity points out that the ivshmem-pci code has some error handling
> cases where it incorrectly tries to use an invalid filedescriptor.
> These generally happen because ivshmem_recv_msg() calls
> qemu_chr_fe_get_msgfd(), which might return -1, but the code in
> process_msg() generally assumes that the file descriptor was provided
> when it was supposed to be. In particular:
>  * the error case in process_msg() only needs to close the fd
>    if one was provided
>  * process_msg_shmem() should fail if no fd was provided

It does even before the patch, because ...

>
> Coverity: CID 1508726
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Disclaimer: tested only with "make check"
> ---
>  hw/misc/ivshmem-pci.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c
> index 5a10bca633d..d47ae739d61 100644
> --- a/hw/misc/ivshmem-pci.c
> +++ b/hw/misc/ivshmem-pci.c
> @@ -479,6 +479,11 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
>      struct stat buf;
>      size_t size;
>  
> +    if (fd < 0) {
> +        error_setg(errp, "server didn't provide fd with shared memory message");
> +        return;
> +    }
> +
>      if (s->ivshmem_bar2) {
>          error_setg(errp, "server sent unexpected shared memory message");
>          close(fd);
           return;
       }

       if (fstat(fd, &buf) < 0) {

... fstat(-1, ...) fails with EBADF.

The additional check gets us a more helpful error message when the
server misbehaves this way.  Fine.

           error_setg_errno(errp, errno,
               "can't determine size of shared memory sent by server");
           close(fd);
           return;
       }

> @@ -553,7 +558,9 @@ static void process_msg(IVShmemState *s, int64_t msg, int fd, Error **errp)
>  
>      if (msg < -1 || msg > IVSHMEM_MAX_PEERS) {
>          error_setg(errp, "server sent invalid message %" PRId64, msg);
> -        close(fd);
> +        if (fd >= 0) {
> +            close(fd);
> +        }

Coverity is overly picky.  close(-1) is *fine*.  Just like free(NULL).

>          return;
>      }

Regardless
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Re: [PATCH] hw/misc/ivshmem-pci: Improve error handling
Posted by Peter Maydell 5 months ago
On Fri, 11 Jul 2025 at 18:04, Markus Armbruster <armbru@redhat.com> wrote:
>
> Peter Maydell <peter.maydell@linaro.org> writes:
>
> > Coverity points out that the ivshmem-pci code has some error handling
> > cases where it incorrectly tries to use an invalid filedescriptor.
> > These generally happen because ivshmem_recv_msg() calls
> > qemu_chr_fe_get_msgfd(), which might return -1, but the code in
> > process_msg() generally assumes that the file descriptor was provided
> > when it was supposed to be. In particular:
> >  * the error case in process_msg() only needs to close the fd
> >    if one was provided
> >  * process_msg_shmem() should fail if no fd was provided

> >      if (msg < -1 || msg > IVSHMEM_MAX_PEERS) {
> >          error_setg(errp, "server sent invalid message %" PRId64, msg);
> > -        close(fd);
> > +        if (fd >= 0) {
> > +            close(fd);
> > +        }
>
> Coverity is overly picky.  close(-1) is *fine*.  Just like free(NULL).

I think there is a distinction here. free(NULL) is documented
to be a correct program action which must have no effect.
close() on a bad file descriptor is documented to be an
error, which the implementation is supposed to diagnose.

Also, Coverity flags this kind of thing up because it tends to
indicate that whoever wrote the code was not actually thinking
about the error condition; so when it gets caught later this
is more by luck than judgement.

thanks
-- PMM