From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41632) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnsmg-0005O8-7u for qemu-devel@nongnu.org; Tue, 03 Dec 2013 11:25:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vnsma-0006h0-Ew for qemu-devel@nongnu.org; Tue, 03 Dec 2013 11:25:14 -0500 Date: Tue, 3 Dec 2013 18:28:37 +0200 From: "Michael S. Tsirkin" Message-ID: <1386087086-3691-7-git-send-email-mst@redhat.com> References: <1386087086-3691-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1386087086-3691-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PATCH 06/23] hpet: fix buffer overrun on invalid state load List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Anthony Liguori CVE-2013-4527 hw/timer/hpet.c buffer overrun hpet is a VARRAY with a uint8 size but static array of 32 To fix, make sure num_timers is valid using post_load hook. Reported-by: Anthony Liguori Signed-off-by: Michael S. Tsirkin --- hw/timer/hpet.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 2eb75ea..acdc874 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -211,6 +211,15 @@ static void update_irq(struct HPETTimer *timer, int set) } } +static void hpet_fix_num_timers(HPETState *s) +{ + if (s->num_timers < HPET_MIN_TIMERS) { + s->num_timers = HPET_MIN_TIMERS; + } else if (s->num_timers > HPET_MAX_TIMERS) { + s->num_timers = HPET_MAX_TIMERS; + } +} + static void hpet_pre_save(void *opaque) { HPETState *s = opaque; @@ -232,6 +241,8 @@ static int hpet_post_load(void *opaque, int version_id) { HPETState *s = opaque; + hpet_fix_num_timers(s); + /* Recalculate the offset between the main counter and guest time */ s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); @@ -719,11 +730,8 @@ static void hpet_realize(DeviceState *dev, Error **errp) sysbus_init_irq(sbd, &s->irqs[i]); } - if (s->num_timers < HPET_MIN_TIMERS) { - s->num_timers = HPET_MIN_TIMERS; - } else if (s->num_timers > HPET_MAX_TIMERS) { - s->num_timers = HPET_MAX_TIMERS; - } + hpet_fix_num_timers(s); + for (i = 0; i < HPET_MAX_TIMERS; i++) { timer = &s->timer[i]; timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, timer); -- MST