All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address
@ 2016-09-15 11:34 P J P
  2016-09-16 17:00 ` Laszlo Ersek
  0 siblings, 1 reply; 3+ messages in thread
From: P J P @ 2016-09-15 11:34 UTC (permalink / raw)
  To: Qemu Developers; +Cc: Michael S. Tsirkin, Qinghao Tang, Prasad J Pandit

From: Prasad J Pandit <pjp@fedoraproject.org>

virtio back end uses set of buffers to facilitate I/O operations.
If its size is too large, 'cpu_physical_memory_map' could return
a null address. This would result in a null dereference
while un-mapping descriptors. Add check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
---
 hw/virtio/virtio.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 15ee3a7..0a4c5b6 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -472,12 +472,14 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
         }
 
         iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
-        iov[num_sg].iov_len = len;
-        addr[num_sg] = pa;
+        if (iov[num_sg].iov_base) {
+            iov[num_sg].iov_len = len;
+            addr[num_sg] = pa;
 
+            pa += len;
+            num_sg++;
+        }
         sz -= len;
-        pa += len;
-        num_sg++;
     }
     *p_num_sg = num_sg;
 }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address
  2016-09-15 11:34 [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address P J P
@ 2016-09-16 17:00 ` Laszlo Ersek
  2016-09-19  9:07   ` P J P
  0 siblings, 1 reply; 3+ messages in thread
From: Laszlo Ersek @ 2016-09-16 17:00 UTC (permalink / raw)
  To: P J P, Qemu Developers
  Cc: Qinghao Tang, Prasad J Pandit, Michael S. Tsirkin, Stefan Hajnoczi

CC Stefan

On 09/15/16 13:34, P J P wrote:
> From: Prasad J Pandit <pjp@fedoraproject.org>
> 
> virtio back end uses set of buffers to facilitate I/O operations.
> If its size is too large, 'cpu_physical_memory_map' could return
> a null address. This would result in a null dereference
> while un-mapping descriptors. Add check to avoid it.
> 
> Reported-by: Qinghao Tang <luodalongde@gmail.com>
> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
> ---
>  hw/virtio/virtio.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 15ee3a7..0a4c5b6 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -472,12 +472,14 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
>          }
>  
>          iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
> -        iov[num_sg].iov_len = len;
> -        addr[num_sg] = pa;
> +        if (iov[num_sg].iov_base) {
> +            iov[num_sg].iov_len = len;
> +            addr[num_sg] = pa;
>  
> +            pa += len;
> +            num_sg++;
> +        }
>          sz -= len;
> -        pa += len;
> -        num_sg++;
>      }
>      *p_num_sg = num_sg;
>  }
> 

I think the situation you describe is a guest bug. Just above the code
that you modify, there's already

    if (!sz) {
        error_report("virtio: zero sized buffers are not allowed");
        exit(1);
    }

I think it would be reasonable to handle this other guest bug similarly:

    if (iov[num_sg].iov_base == NULL) {
        error_report("virtio: bogus descriptor or out of resources");
        exit(EXIT_FAILURE);
    }

The main message is of course "bogus descriptor". OTOH,
cpu_physical_memory_map() / address_space_map() can return NULL for
multiple reasons, not all of which seem guest errors: the loop in
virtqueue_map_desc() handles the case when cpu_physical_memory_map()
cannot map the entire area requested by the descriptor in a single go,
and then mapping (part) of the remaining area might fail due to resource
exhaustion in QEMU (see "resources needed to perform the mapping are
exhausted" on address_space_map()).

So maybe those error returns from address_space_map() should be
disentangled first. (Although, the only difference they'd make at this
point would be in the error message when we bail out anyway.)

So, unless Stefan or someone else has a better idea, I suggest the above
error message, and exit(EXIT_FAILURE). Silently skipping a part (or all
remaining parts) of the area requested by the descriptor is unlikely to
produce predictable results for the guest (and the user).

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address
  2016-09-16 17:00 ` Laszlo Ersek
@ 2016-09-19  9:07   ` P J P
  0 siblings, 0 replies; 3+ messages in thread
From: P J P @ 2016-09-19  9:07 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Qemu Developers, Qinghao Tang, Stefan Hajnoczi, Michael S. Tsirkin

+-- On Fri, 16 Sep 2016, Laszlo Ersek wrote --+
| CC Stefan
| I think it would be reasonable to handle this other guest bug similarly:
| 
|     if (iov[num_sg].iov_base == NULL) {
|         error_report("virtio: bogus descriptor or out of resources");
|         exit(EXIT_FAILURE);
|     }
...
| So, unless Stefan or someone else has a better idea, I suggest the above
| error message, and exit(EXIT_FAILURE).

I have sent a revised patch v2. Thank you.
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-09-19  9:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-15 11:34 [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address P J P
2016-09-16 17:00 ` Laszlo Ersek
2016-09-19  9:07   ` P J P

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.