Patchwork [RFT,01/15] hpet: Catch out-of-bounds timer access

login
register
mail settings
Submitter Jan Kiszka
Date May 24, 2010, 8:13 p.m.
Message ID <8a1aa09875d202957645ecf4b8eb67db935d175c.1274732025.git.jan.kiszka@web.de>
Download mbox | patch
Permalink /patch/53457/
State New
Headers show

Comments

Jan Kiszka - May 24, 2010, 8:13 p.m.
From: Jan Kiszka <jan.kiszka@siemens.com>

Also prevent out-of-bounds write access to the timers but don't spam the
host console if it triggers.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
Juan Quintela - May 24, 2010, 8:34 p.m.
Jan Kiszka <jan.kiszka@web.de> wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> Also prevent out-of-bounds write access to the timers but don't spam the
> host console if it triggers.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  hw/hpet.c |    6 +++++-
>  1 files changed, 5 insertions(+), 1 deletions(-)
>
> diff --git a/hw/hpet.c b/hw/hpet.c
> index 8729fb2..1980906 100644
> --- a/hw/hpet.c
> +++ b/hw/hpet.c
> @@ -294,7 +294,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
>      if (index >= 0x100 && index <= 0x3ff) {
>          uint8_t timer_id = (addr - 0x100) / 0x20;
>          if (timer_id > HPET_NUM_TIMERS - 1) {
> -            printf("qemu: timer id out of range\n");
> +            DPRINTF("qemu: timer id out of range\n");
>              return 0;
>          }
>          HPETTimer *timer = &s->timer[timer_id];
> @@ -383,6 +383,10 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
>          DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);

if you are going to check timer_id, check it before accessing the array?

>          HPETTimer *timer = &s->timer[timer_id];
>  
> +        if (timer_id > HPET_NUM_TIMERS - 1) {
> +            DPRINTF("qemu: timer id out of range\n");
> +            return;
> +        }
>          switch ((addr - 0x100) % 0x20) {
>              case HPET_TN_CFG:
>                  DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
Jan Kiszka - May 24, 2010, 8:36 p.m.
Juan Quintela wrote:
> Jan Kiszka <jan.kiszka@web.de> wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> Also prevent out-of-bounds write access to the timers but don't spam the
>> host console if it triggers.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  hw/hpet.c |    6 +++++-
>>  1 files changed, 5 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/hpet.c b/hw/hpet.c
>> index 8729fb2..1980906 100644
>> --- a/hw/hpet.c
>> +++ b/hw/hpet.c
>> @@ -294,7 +294,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
>>      if (index >= 0x100 && index <= 0x3ff) {
>>          uint8_t timer_id = (addr - 0x100) / 0x20;
>>          if (timer_id > HPET_NUM_TIMERS - 1) {
>> -            printf("qemu: timer id out of range\n");
>> +            DPRINTF("qemu: timer id out of range\n");
>>              return 0;
>>          }
>>          HPETTimer *timer = &s->timer[timer_id];
>> @@ -383,6 +383,10 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
>>          DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
> 
> if you are going to check timer_id, check it before accessing the array?

That's just address arithmetic, nothing is dereferenced at this point.

Jan
Juan Quintela - May 24, 2010, 8:50 p.m.
Jan Kiszka <jan.kiszka@web.de> wrote:
> Juan Quintela wrote:
>> Jan Kiszka <jan.kiszka@web.de> wrote:
>>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>>
>>> Also prevent out-of-bounds write access to the timers but don't spam the
>>> host console if it triggers.
>>>
>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>> ---
>>>  hw/hpet.c |    6 +++++-
>>>  1 files changed, 5 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/hw/hpet.c b/hw/hpet.c
>>> index 8729fb2..1980906 100644
>>> --- a/hw/hpet.c
>>> +++ b/hw/hpet.c
>>> @@ -294,7 +294,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
>>>      if (index >= 0x100 && index <= 0x3ff) {
>>>          uint8_t timer_id = (addr - 0x100) / 0x20;
>>>          if (timer_id > HPET_NUM_TIMERS - 1) {
>>> -            printf("qemu: timer id out of range\n");
>>> +            DPRINTF("qemu: timer id out of range\n");
>>>              return 0;
>>>          }
>>>          HPETTimer *timer = &s->timer[timer_id];
>>> @@ -383,6 +383,10 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
>>>          DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
>> 
>> if you are going to check timer_id, check it before accessing the array?
>
> That's just address arithmetic, nothing is dereferenced at this point.

hahahahahha

/me back to the pointer class.

Later, Juan.

Patch

diff --git a/hw/hpet.c b/hw/hpet.c
index 8729fb2..1980906 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -294,7 +294,7 @@  static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
     if (index >= 0x100 && index <= 0x3ff) {
         uint8_t timer_id = (addr - 0x100) / 0x20;
         if (timer_id > HPET_NUM_TIMERS - 1) {
-            printf("qemu: timer id out of range\n");
+            DPRINTF("qemu: timer id out of range\n");
             return 0;
         }
         HPETTimer *timer = &s->timer[timer_id];
@@ -383,6 +383,10 @@  static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
         DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
         HPETTimer *timer = &s->timer[timer_id];
 
+        if (timer_id > HPET_NUM_TIMERS - 1) {
+            DPRINTF("qemu: timer id out of range\n");
+            return;
+        }
         switch ((addr - 0x100) % 0x20) {
             case HPET_TN_CFG:
                 DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");