From patchwork Mon Nov 12 21:25:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 996660 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PJ36Qcu+"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42v3km4jcgz9rxp for ; Tue, 13 Nov 2018 08:27:44 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 58584C21E9F; Mon, 12 Nov 2018 21:26:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id E7536C22499; Mon, 12 Nov 2018 21:26:09 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A6200C2248E; Mon, 12 Nov 2018 21:25:57 +0000 (UTC) Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by lists.denx.de (Postfix) with ESMTPS id 72EE0C222D9 for ; Mon, 12 Nov 2018 21:25:56 +0000 (UTC) Received: by mail-wm1-f68.google.com with SMTP id f10-v6so9876920wme.3 for ; Mon, 12 Nov 2018 13:25:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oFwmLXsZ14ZifR69TMtq82xkNpFriL/IG1MWVklLQ4E=; b=PJ36Qcu+4iRWSGe+NVBcnRIzDojF2MDzwPOFRdgcW6tjlB8bhH89gybtZhfXqcNRhR r7RBduScEgTKlIMjUE0K+YfWyYmn8lJGz6khQRTVxPoh4Bt3R91D+cQPwOnn60i2aSP0 /VWwgcpIWfvV0ucZa/Sy0XQJimBS9G7318xU/f80IR/yvuusRLCBazpQaYjZXmBv1MTy KudwVqbOARwtzVQrIXReu3KB9bzzA/3drK7CDcK6FAe7QsRHdUFurdqSMfySwiUbmoay wFgYhs8WuiCvsH1tLEkphgG1xULAav1bpQdFoVLao87vdnV09hOSEAgiOlqfFs1SCPho 3iMg== 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:in-reply-to :references; bh=oFwmLXsZ14ZifR69TMtq82xkNpFriL/IG1MWVklLQ4E=; b=At5RpKrc93osC/MO3imYWEkpk5G/uPcipxEeB338yH+JhpkzdFLnd/9wPVfrJCb3Dr 65b1iNeuDmvSfrMZHNT4yqIlXAfcby4iVKFhqPINNhyKI7QdnJ65ziHDyMR0xT60NF3C RAzqf3oG55V/4+3TQtp1OmQHcm5Isw3g/frG5wCNRp4A2a8qoTwLLoI4OEvOrsmh/rEN cGRFnhZ31lgxbhTNg6R+fYCPVU5gahVxz/4WfQeOGf/9MNGBNv8iwq+TVp7es7x+YIcO klaue06TtApGoJ7YKj6lEL0tnSfviEUir2O5GQB8sWtbi/5RVdFpapZvLruo7ShizRL1 waIw== X-Gm-Message-State: AGRZ1gKFZJ2hko6RQoT2RmqzhmJg/Cm3xWBHLgoSxXbVvk2nCSH9Bpd3 ugAUbqdkcsD4qpBVoONxOpY= X-Google-Smtp-Source: AJdET5d4xm0d1QdGyaZ3xz1qgrlEseq3V4XSsaMioUrkqAs/Y+GE+5JLttX45thKYrfkkq2z25nrqw== X-Received: by 2002:a1c:f514:: with SMTP id t20-v6mr1047580wmh.129.1542057956020; Mon, 12 Nov 2018 13:25:56 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:456c:50ae:6b7:768d]) by smtp.gmail.com with ESMTPSA id x14sm742690wrm.65.2018.11.12.13.25.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Nov 2018 13:25:55 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de Date: Mon, 12 Nov 2018 22:25:31 +0100 Message-Id: <20181112212532.13126-4-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181112212532.13126-1-simon.k.r.goldschmidt@gmail.com> References: <20181112212532.13126-1-simon.k.r.goldschmidt@gmail.com> Cc: Joe Hershberger , Heinrich Schuchardt , Alexander Graf , Andrea Barisani Subject: [U-Boot] [PATCH 3/4] fs: prevent overwriting reserved memory X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This fixes CVE-2018-18440 ("insufficient boundary checks in filesystem image load") by using lmb to check the load size of a file against reserved memory addresses. Signed-off-by: Simon Goldschmidt --- fs/fs.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- include/lmb.h | 2 ++ lib/lmb.c | 13 ++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/fs/fs.c b/fs/fs.c index adae98d021..4baf6b1c39 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size) return ret; } -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, - loff_t *actread) +#ifdef CONFIG_LMB +/* Check if a file may be read to the given address */ +static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, + loff_t len, struct fstype_info *info) +{ + struct lmb lmb; + int ret; + loff_t size; + loff_t read_len; + + /* get the actual size of the file */ + ret = info->size(filename, &size); + if (ret) + return ret; + if (offset >= size) { + /* offset >= EOF, no bytes will be written */ + return 0; + } + read_len = size - offset; + + /* limit to 'len' if it is smaller */ + if (len && len < read_len) + read_len = len; + + lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start, + gd->bd->bi_dram[0].size, (void *)gd->fdt_blob); + lmb_dump_all(&lmb); + + if (lmb_alloc_addr(&lmb, addr, read_len) == addr) + return 0; + + printf("** Reading file would overwrite reserved memory **\n"); + return -1; +} +#endif + +static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, + int do_lmb_check, loff_t *actread) { struct fstype_info *info = fs_get_info(fs_type); void *buf; int ret; +#ifdef CONFIG_LMB + if (do_lmb_check) { + ret = fs_read_lmb_check(filename, addr, offset, len, info); + if (ret) + return ret; + } +#endif + /* * We don't actually know how many bytes are being read, since len==0 * means read the whole file. @@ -451,6 +495,12 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, return ret; } +int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, + loff_t *actread) +{ + return _fs_read(filename, addr, offset, len, 0, actread); +} + int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, loff_t *actwrite) { @@ -621,7 +671,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], pos = 0; time = get_timer(0); - ret = fs_read(filename, addr, pos, bytes, &len_read); + ret = _fs_read(filename, addr, pos, bytes, 1, &len_read); time = get_timer(time); if (ret < 0) return 1; diff --git a/include/lmb.h b/include/lmb.h index bc06f175e1..810a37d5a5 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -31,6 +31,8 @@ struct lmb { extern struct lmb lmb; extern void lmb_init(struct lmb *lmb); +extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, + phys_size_t size, void *fdt_blob); extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); diff --git a/lib/lmb.c b/lib/lmb.c index c3af2fd5fc..99a4aaa09e 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -104,6 +104,19 @@ void lmb_init(struct lmb *lmb) lmb->reserved.size = 0; } +/* Initialize the struct, add memory and call arch/board reserve functions */ +void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size, + void *fdt_blob) +{ + lmb_init(lmb); + lmb_add(lmb, base, size); + arch_lmb_reserve(lmb); + board_lmb_reserve(lmb); + + if (IMAGE_ENABLE_OF_LIBFDT) + boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); +} + /* This routine called with relocation disabled. */ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size) {