From patchwork Fri Feb 26 15:20:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 8438661 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6083AC0553 for ; Fri, 26 Feb 2016 15:37:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B2C9B203B1 for ; Fri, 26 Feb 2016 15:37:54 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 89BD120392 for ; Fri, 26 Feb 2016 15:37:53 +0000 (UTC) Received: from localhost ([::1]:50595 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aZKSm-0002t9-VN for patchwork-qemu-devel@patchwork.kernel.org; Fri, 26 Feb 2016 10:37:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37349) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aZKC4-0007XK-Cp for qemu-devel@nongnu.org; Fri, 26 Feb 2016 10:20:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aZKC3-0004nb-Ee for qemu-devel@nongnu.org; Fri, 26 Feb 2016 10:20:36 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:56000) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aZKC3-0004nL-7A for qemu-devel@nongnu.org; Fri, 26 Feb 2016 10:20:35 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84) (envelope-from ) id 1aZKC2-0003Oi-TH for qemu-devel@nongnu.org; Fri, 26 Feb 2016 15:20:34 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 26 Feb 2016 15:20:19 +0000 Message-Id: <1456500025-28761-15-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1456500025-28761-1-git-send-email-peter.maydell@linaro.org> References: <1456500025-28761-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 14/20] ARM: PL061: Checking register r/w accesses to reserved area X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wei Huang pl061.c emulates two GPIO devices, ARM PL061 and TI Stellaris, which share the same read/write functions (pl061_read and pl061_write). However PL061 and Stellaris have different GPIO register definitions and pl061_read()/pl061_write() doesn't check it. This patch enforces checking on offset, preventing R/W into the reserved memory area. Signed-off-by: Wei Huang Message-id: 1455814580-17699-1-git-send-email-wei@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/gpio/pl061.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index 5ece8b0..29dc7fc 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -60,6 +60,7 @@ typedef struct PL061State { qemu_irq irq; qemu_irq out[8]; const unsigned char *id; + uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */ } PL061State; static const VMStateDescription vmstate_pl061 = { @@ -152,12 +153,15 @@ static uint64_t pl061_read(void *opaque, hwaddr offset, { PL061State *s = (PL061State *)opaque; - if (offset >= 0xfd0 && offset < 0x1000) { - return s->id[(offset - 0xfd0) >> 2]; - } if (offset < 0x400) { return s->data & (offset >> 2); } + if (offset >= s->rsvd_start && offset <= 0xfcc) { + goto err_out; + } + if (offset >= 0xfd0 && offset < 0x1000) { + return s->id[(offset - 0xfd0) >> 2]; + } switch (offset) { case 0x400: /* Direction */ return s->dir; @@ -198,10 +202,12 @@ static uint64_t pl061_read(void *opaque, hwaddr offset, case 0x528: /* Analog mode select */ return s->amsel; default: - qemu_log_mask(LOG_GUEST_ERROR, - "pl061_read: Bad offset %x\n", (int)offset); - return 0; + break; } +err_out: + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_read: Bad offset %x\n", (int)offset); + return 0; } static void pl061_write(void *opaque, hwaddr offset, @@ -216,6 +222,9 @@ static void pl061_write(void *opaque, hwaddr offset, pl061_update(s); return; } + if (offset >= s->rsvd_start) { + goto err_out; + } switch (offset) { case 0x400: /* Direction */ s->dir = value & 0xff; @@ -274,10 +283,13 @@ static void pl061_write(void *opaque, hwaddr offset, s->amsel = value & 0xff; break; default: - qemu_log_mask(LOG_GUEST_ERROR, - "pl061_write: Bad offset %x\n", (int)offset); + goto err_out; } pl061_update(s); + return; +err_out: + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_write: Bad offset %x\n", (int)offset); } static void pl061_reset(DeviceState *dev) @@ -347,6 +359,7 @@ static void pl061_luminary_init(Object *obj) PL061State *s = PL061(obj); s->id = pl061_id_luminary; + s->rsvd_start = 0x52c; } static void pl061_init(Object *obj) @@ -354,6 +367,7 @@ static void pl061_init(Object *obj) PL061State *s = PL061(obj); s->id = pl061_id; + s->rsvd_start = 0x424; } static void pl061_class_init(ObjectClass *klass, void *data)