diff mbox

[2/2] ivshmem: validate incoming_posn value from server

Message ID 1396249691-29990-3-git-send-email-stefanha@redhat.com
State New
Headers show

Commit Message

Stefan Hajnoczi March 31, 2014, 7:08 a.m. UTC
Check incoming_posn to avoid out-of-bounds array accesses if the ivshmem
server on the host sends invalid values.

Cc: Cam Macdonell <cam@cs.ualberta.ca>
Reported-by: Sebastian Krahmer <krahmer@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/misc/ivshmem.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Peter Maydell April 14, 2014, 2:26 p.m. UTC | #1
On 31 March 2014 08:08, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> Check incoming_posn to avoid out-of-bounds array accesses if the ivshmem
> server on the host sends invalid values.
>
> Cc: Cam Macdonell <cam@cs.ualberta.ca>
> Reported-by: Sebastian Krahmer <krahmer@suse.de>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  hw/misc/ivshmem.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
> index 78363ce..25c22b7 100644
> --- a/hw/misc/ivshmem.c
> +++ b/hw/misc/ivshmem.c
> @@ -383,6 +383,9 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
>      if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
>          return;
>      }
> +    if (posn < 0 || posn > s->nb_peers) {
> +        return;
> +    }
>
>      guest_curr_max = s->peers[posn].nb_eventfds;

Shouldn't the upper bound check be checking ">=", not ">" ?

thanks
-- PMM
Andreas Färber April 14, 2014, 4:27 p.m. UTC | #2
Am 14.04.2014 16:26, schrieb Peter Maydell:
> On 31 March 2014 08:08, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>> Check incoming_posn to avoid out-of-bounds array accesses if the ivshmem
>> server on the host sends invalid values.
>>
>> Cc: Cam Macdonell <cam@cs.ualberta.ca>
>> Reported-by: Sebastian Krahmer <krahmer@suse.de>
>> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
>> ---
>>  hw/misc/ivshmem.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
>> index 78363ce..25c22b7 100644
>> --- a/hw/misc/ivshmem.c
>> +++ b/hw/misc/ivshmem.c
>> @@ -383,6 +383,9 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
>>      if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
>>          return;
>>      }
>> +    if (posn < 0 || posn > s->nb_peers) {
>> +        return;
>> +    }
>>
>>      guest_curr_max = s->peers[posn].nb_eventfds;
> 
> Shouldn't the upper bound check be checking ">=", not ">" ?

Indeed, looks like it. We're allocating s->nb_peers * sizeof(Peer) in
increase_dynamic_storage() just below.

Regards,
Andreas
diff mbox

Patch

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 78363ce..25c22b7 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -383,6 +383,9 @@  static void close_guest_eventfds(IVShmemState *s, int posn)
     if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
         return;
     }
+    if (posn < 0 || posn > s->nb_peers) {
+        return;
+    }
 
     guest_curr_max = s->peers[posn].nb_eventfds;
 
@@ -433,6 +436,12 @@  static void ivshmem_read(void *opaque, const uint8_t * buf, int size)
     }
 
     memcpy(&incoming_posn, buf, sizeof(long));
+
+    if (incoming_posn < -1) {
+        IVSHMEM_DPRINTF("invalid incoming_posn %ld\n", incoming_posn);
+        return;
+    }
+
     /* pick off s->server_chr->msgfd and store it, posn should accompany msg */
     tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr);
     IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd);