From patchwork Fri Oct 19 20:39:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenwen Wang X-Patchwork-Id: 10650167 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 339B914E5 for ; Fri, 19 Oct 2018 20:48:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 205032237D for ; Fri, 19 Oct 2018 20:48:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0FC0A22BF1; Fri, 19 Oct 2018 20:48:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BA212237D for ; Fri, 19 Oct 2018 20:48:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726321AbeJTE4K (ORCPT ); Sat, 20 Oct 2018 00:56:10 -0400 Received: from mta-p6.oit.umn.edu ([134.84.196.206]:45578 "EHLO mta-p6.oit.umn.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726157AbeJTE4K (ORCPT ); Sat, 20 Oct 2018 00:56:10 -0400 X-Greylist: delayed 542 seconds by postgrey-1.27 at vger.kernel.org; Sat, 20 Oct 2018 00:56:09 EDT Received: from localhost (unknown [127.0.0.1]) by mta-p6.oit.umn.edu (Postfix) with ESMTP id DCD66DF for ; Fri, 19 Oct 2018 20:39:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at umn.edu Received: from mta-p6.oit.umn.edu ([127.0.0.1]) by localhost (mta-p6.oit.umn.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cjUOoAc10gmq for ; Fri, 19 Oct 2018 15:39:26 -0500 (CDT) Received: from mail-io1-f69.google.com (mail-io1-f69.google.com [209.85.166.69]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mta-p6.oit.umn.edu (Postfix) with ESMTPS id AEE71B48 for ; Fri, 19 Oct 2018 15:39:26 -0500 (CDT) Received: by mail-io1-f69.google.com with SMTP id s15-v6so31316512iob.11 for ; Fri, 19 Oct 2018 13:39:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=umn.edu; s=google; h=from:to:cc:subject:date:message-id; bh=8xYoiRynmnEoMoJLcYQvBlb5siR4tDJjtLBRz6IrP84=; b=bTr4bHyVTmxp5TjN/XzPj31Q574T+9i6j5m1ZY9g+7lbZMWVNMBuObw1+S2JYbnmFx wnFA4UGSE0WZKx//S9EgwdSy5cKMwP33/VsDVwxXz+4kX65i1T6KLD7y0LhN6z8XB8ZR g6sXeTwlyAB908cg9posXrTJrFsOOYPrik/r9xMwUUhMF/2mZcO72OCjLKio/LLv2cnX Vso7vQvgBw2LJsj84mSTlm3qgyMsvkkuoBGU6QwUmz1XnAUUwruuTE0WJHDqR8yzvgQ7 PlhxTR+Gv1sAV86yX3mZtULOiOLzugvEyQIYoCPo5qlLN++7ffkx6vFByI6eGjgK0bh0 G9Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=8xYoiRynmnEoMoJLcYQvBlb5siR4tDJjtLBRz6IrP84=; b=qc4ithaoPAZA5PzHF24Jmpmp5dF6ieNsfk94ap6L85QXrJkv92Vr/RU80AMMtEFqjt fSQHJR7+0Kgulq3+3jgqsCqGFguksssgKhygyI7qOguJ1sUCijtn8vbKnFHvTlPPAY3u OaKbBS4X9aaNfuvMgRW+cfhveaSzkjaOxWC0r6Ji4VhjmD8d/M+/tWudbNqXiThMidSv PwWLr2g1/97cohUCdRvK4demBLk8HefkIbXGjGdk+182Skm2vWeMZz2r3iom3I867pjo qFAl/fRoQdmX73AZahDrLDjJfwna3hGFI1ke7SiiApv8TaA23szDWX4LbdyjA+plYnrD 3KlQ== X-Gm-Message-State: AGRZ1gI09Tf7rsOjpgm29jwcR0VdblAv3R9dRfv1kyfddOXgIZsx03z0 ZehuGIL3pZJEfJiYsqiCJ5ZWyNEfuPgFH1jtRsJVgGvm5uEKx7puEMiI1Co4x5wxycpdZbG5vsN cKsPREuqTXrypB7IcueIXxWDTCWU= X-Received: by 2002:a5e:dd0a:: with SMTP id t10-v6mr3964760iop.62.1539981566037; Fri, 19 Oct 2018 13:39:26 -0700 (PDT) X-Google-Smtp-Source: AJdET5e9D2AwVhI+4ifydxZ1szmWyEZb8Y/yYPv7TgFl9kHsKXwqwRsV16mH7W/yz9VE6stCb570SA== X-Received: by 2002:a5e:dd0a:: with SMTP id t10-v6mr3964752iop.62.1539981565780; Fri, 19 Oct 2018 13:39:25 -0700 (PDT) Received: from cs-u-cslp16.cs.umn.edu (cs-u-cslp16.cs.umn.edu. [134.84.121.95]) by smtp.gmail.com with ESMTPSA id 82-v6sm1595304ita.17.2018.10.19.13.39.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 19 Oct 2018 13:39:24 -0700 (PDT) From: Wenwen Wang To: Wenwen Wang Cc: Kangjie Lu , Thomas Winischhofer , Bartlomiej Zolnierkiewicz , dri-devel@lists.freedesktop.org (open list:FRAMEBUFFER LAYER), linux-fbdev@vger.kernel.org (open list:FRAMEBUFFER LAYER), linux-kernel@vger.kernel.org (open list) Subject: [PATCH] video: fbdev: sis: fix a missing-check bug Date: Fri, 19 Oct 2018 15:39:17 -0500 Message-Id: <1539981557-13590-1-git-send-email-wang6495@umn.edu> X-Mailer: git-send-email 2.7.4 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In sisfb_find_rom(), the official pci ROM is checked to see whether it contains the expected value at specific locations. This is done by firstly mapping the rom into the IO memory region 'rom_base' and then invoking sisfb_check_rom() to perform the checks. If the checks succeed, i.e., sisfb_check_rom() returns 1, the whole content of the rom is then copied to 'myrombase' through memcpy_fromio(). The problem here is that the checks are conducted on the IO region 'rom_base' directly. Given that the device also has the permission to access the IO region, it is possible that a malicious device controlled by an attacker can race to modify the values in the region after the checks but before memcpy_fromio(). By doing so, the attacker can supply unexpected roms, which can cause undefined behavior of the kernel and introduce potential security risk. The following for loop also has a similar issue. To avoid the above issue, this patch firstly copies the content of the rom and then performs the checks on the copied version. If all the checks are satisfied, the copied version will then be returned. Signed-off-by: Wenwen Wang --- drivers/video/fbdev/sis/sis_main.c | 52 ++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 20aff90..a2d8051 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -4089,29 +4089,29 @@ static int __init sisfb_setup(char *options) } #endif -static int sisfb_check_rom(void __iomem *rom_base, +static int sisfb_check_rom(unsigned char *rom_base, struct sis_video_info *ivideo) { - void __iomem *rom; + unsigned char *rom; int romptr; - if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) + if ((*rom_base != 0x55) || (*(rom_base + 1) != 0xaa)) return 0; - romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8)); + romptr = (*(rom_base + 0x18) | (*(rom_base + 0x19) << 8)); if(romptr > (0x10000 - 8)) return 0; rom = rom_base + romptr; - if((readb(rom) != 'P') || (readb(rom + 1) != 'C') || - (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) + if ((*(rom) != 'P') || (*(rom + 1) != 'C') || + (*(rom + 2) != 'I') || (*(rom + 3) != 'R')) return 0; - if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor) + if ((*(rom + 4) | (*(rom + 5) << 8)) != ivideo->chip_vendor) return 0; - if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id) + if ((*(rom + 6) | (*(rom + 7) << 8)) != ivideo->chip_id) return 0; return 1; @@ -4124,6 +4124,10 @@ static unsigned char *sisfb_find_rom(struct pci_dev *pdev) unsigned char *myrombase = NULL; size_t romsize; + myrombase = vmalloc(65536); + if (!myrombase) + return NULL; + /* First, try the official pci ROM functions (except * on integrated chipsets which have no ROM). */ @@ -4131,20 +4135,15 @@ static unsigned char *sisfb_find_rom(struct pci_dev *pdev) if(!ivideo->nbridge) { if((rom_base = pci_map_rom(pdev, &romsize))) { - - if(sisfb_check_rom(rom_base, ivideo)) { - - if((myrombase = vmalloc(65536))) { - memcpy_fromio(myrombase, rom_base, - (romsize > 65536) ? 65536 : romsize); - } - } + memcpy_fromio(myrombase, rom_base, + (romsize > 65536) ? 65536 : romsize); pci_unmap_rom(pdev, rom_base); + + if (sisfb_check_rom(myrombase, ivideo)) + return myrombase; } } - if(myrombase) return myrombase; - /* Otherwise do it the conventional way. */ #if defined(__i386__) || defined(__x86_64__) @@ -4156,24 +4155,17 @@ static unsigned char *sisfb_find_rom(struct pci_dev *pdev) rom_base = ioremap(temp, 65536); if (!rom_base) continue; - - if (!sisfb_check_rom(rom_base, ivideo)) { - iounmap(rom_base); - continue; - } - - if ((myrombase = vmalloc(65536))) - memcpy_fromio(myrombase, rom_base, 65536); - + memcpy_fromio(myrombase, rom_base, 65536); iounmap(rom_base); - break; + if (sisfb_check_rom(myrombase, ivideo)) + return myrombase; } } #endif - - return myrombase; + vfree(myrombase); + return NULL; } static void sisfb_post_map_vram(struct sis_video_info *ivideo,