From c5466bb75a462a6b609dbd4bffc4551e32732d71 Mon Sep 17 00:00:00 2001
Message-Id: <c5466bb75a462a6b609dbd4bffc4551e32732d71.1343216154.git.minovotn@redhat.com>
From: Amit Shah <amit.shah@redhat.com>
Date: Fri, 15 Jun 2012 09:03:43 +0200
Subject: [PATCH] qdev-properties: restrict uint32 input values between 0 and
 UINT32_MAX

RH-Author: Amit Shah <amit.shah@redhat.com>
Message-id: <85e8ba8a2a2f286a0c6d0cd3b82cbc6129ee6ea3.1339750472.git.amit.shah@redhat.com>
Patchwork-id: 39979
O-Subject: [RHEL6.4 qemu PATCH] qdev-properties: restrict uint32 input values between 0 and UINT32_MAX
Bugzilla: 797728
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
RH-Acked-by: Amos Kong <akong@redhat.com>

Bugzilla: 797728

qemu-kvm -m 128 -device virtio-serial \
         -device virtserialport,nr=4294967297

as well as

qemu-kvm -m 128 -device virtio-serial \
         -device virtserialport,nr=-1

are accepted even though 'nr' is a uint32-type property.  Upstream's
visitor interface does the appropriate bounds-check.

There are other functions (parse_uint{8,16,64}_t) that don't check
bounds as well.  Should we fix them as well?

A uint32-type qdev property could take values -1, 4294967297, etc.,
without an error.

Add limit checking to the parse_uint32_t() function.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 hw/qdev-properties.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/qdev-properties.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 925a5f2..00afb1c 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -127,15 +127,19 @@ PropertyInfo qdev_prop_uint16 = {
 
 static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
 {
+    int64_t val;
     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
     char *end;
 
     /* accept both hex and decimal */
-    *ptr = strtoul(str, &end, 0);
+    val = strtoll(str, &end, 0);
     if ((*end != '\0') || (end == str)) {
         return -EINVAL;
     }
-
+    if (val < 0 || val > UINT32_MAX) {
+        return -EINVAL;
+    }
+    *ptr = val;
     return 0;
 }
 
-- 
1.7.10.4

