Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3610220imm; Fri, 19 Oct 2018 13:40:05 -0700 (PDT) X-Google-Smtp-Source: ACcGV610FWosLkdBaymQPfZzWGkB7/9VInlZr5zmr3GpR3gLlQ4dIPDDQR8OSIaNEQBbOo7CDAQV X-Received: by 2002:a17:902:9303:: with SMTP id bc3-v6mr6531816plb.206.1539981605778; Fri, 19 Oct 2018 13:40:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539981605; cv=none; d=google.com; s=arc-20160816; b=zquhQ6FO430sUVP19FicwZOAruQeIP16tDaJO9I5cFWVIU61elhwdYUeakUUCmykBH 6s3jjRTh6A1X+lJhFhXakJhFJvqZKRXMajO/ktw1MEixYjm9KMuiCQ7+kXygXi6lpXUO N5ADbFqqlGgI3ch1yhxYvalOkBrrylVSNw3a9mp4h8Ovqey6iSVNFCj3LThdRv5LYIw9 ol4xdulHflEciIioB5AjxThu9uWDm7puYDP0wwMik9rC/UhtT0HxV4ypBmPQ5wK4t9/w +FL/vyIfS5Q2rlufAiTPrvafBptT6QBFjZt/TxhunQENVKR8FwdJ9uAQL6uLbsdd1kPp cOew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=8xYoiRynmnEoMoJLcYQvBlb5siR4tDJjtLBRz6IrP84=; b=g55+dzB0a8bWY58w7Bux1MR/SnCM+Bw5uTUhUiSif3uTOI2SdfjCvR8WRQO36VnIWa OWaW6UL8lOJIPZHJKgrTnJu0sHFRbxodL//qh2TShA8yT5PMYlSc0T3PDfYZeDJ/r+tu 2NoYK8i/hwGdhAK1uFnW2WkEn+RgrwQB8yiCDy3L7baCPhq+BapL/q83NGE1qca8pcka 2i2V/VsbnvFI+/YE2YR45XXs2x2j9tCpxTIrjzTRL60szHHCV3yyiH6W1J819k3ymSyM n7+ub+pTmDXqzHmmqh1x0HlU0bcbQPd0Un0opk9tA1nx1OwVVh5t6vAkIPmXaQLAKqKw UxdQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@umn.edu header.s=google header.b=bTr4bHyV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=umn.edu Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u127-v6si25414640pgc.234.2018.10.19.13.39.50; Fri, 19 Oct 2018 13:40:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@umn.edu header.s=google header.b=bTr4bHyV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=umn.edu Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726546AbeJTErI (ORCPT + 99 others); Sat, 20 Oct 2018 00:47:08 -0400 Received: from mta-p7.oit.umn.edu ([134.84.196.207]:45000 "EHLO mta-p7.oit.umn.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726246AbeJTErI (ORCPT ); Sat, 20 Oct 2018 00:47:08 -0400 Received: from localhost (unknown [127.0.0.1]) by mta-p7.oit.umn.edu (Postfix) with ESMTP id EBC4ECFD for ; Fri, 19 Oct 2018 20:39:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at umn.edu Received: from mta-p7.oit.umn.edu ([127.0.0.1]) by localhost (mta-p7.oit.umn.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8j3vWuAI9_Xb for ; Fri, 19 Oct 2018 15:39:26 -0500 (CDT) Received: from mail-io1-f70.google.com (mail-io1-f70.google.com [209.85.166.70]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mta-p7.oit.umn.edu (Postfix) with ESMTPS id BC83180E for ; Fri, 19 Oct 2018 15:39:26 -0500 (CDT) Received: by mail-io1-f70.google.com with SMTP id f9-v6so31255037iok.23 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=iNnLrj1cq4kZFjNwJ3wXUWon5T4vEL4fjCHtlaMhj6G6Ln/1Py9uBFDsymVqChWTCy nqCiq9NlPY9ooZQ2ITXqzgLokV7ll9XmWBkpim6nseY3+YWVGQxchd5M10hUntNkwfvt 0I3UlUI4VJI40gO1yHr1R1UuzcbHTMlwtSMTEObvQ1o9U7Z0C90KTkvc5qVF2sYrm42/ lrHBtwRDywkkMuL5Tmhfvio8exFZqAcpE4tThgzfUOTKQVOjRPV2wUilu1wVe9w04EYU PT+E7gKoYhvNquEI0izFG/TfrVr0uWBQvJsKzcnxNDb09vMBOTIb1jRqmZ8ldTC7A7JG NRBQ== X-Gm-Message-State: AGRZ1gKstlU1fdAeeWrBJDAq6U3x6D+EkXzO4hghBKVjLom2or2HdCn2 Ny9P53RA79hL1FTltQpczzUI9iIz2K+x6d1T7mYHJYlx6cRh93dlYnRRZ+u7sTFXrdz2EKCNHZp hxaabxeORaVARzUbnVuypu12hswc0 X-Received: by 2002:a5e:dd0a:: with SMTP id t10-v6mr3964761iop.62.1539981566037; Fri, 19 Oct 2018 13:39:26 -0700 (PDT) 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-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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, -- 2.7.4