From patchwork Wed Jun 13 21:23:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 929093 X-Patchwork-Delegate: richard@nod.at 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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nod.at Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="uZ9rP8wQ"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 415fth2bcYz9s2g for ; Thu, 14 Jun 2018 07:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=AN2DAWMGAn6AYjGaU6R6OZLH27ezaWohdwqUnEWr6GQ=; b=uZ9rP8wQvxNhA/ulgNTz9vKUyb +sznH9nq3L8otgZRM5OTIH3qEBhkw60U/2SSy9DUckeHQnWlvLKweoYnRvt7oSfvJUXqWTh9CwAkE xAEbCfSua+pV63LP/BYbUGXmGqW+5xFGhtN09CWtEeY9mUfg9CU6WQonUFqXLjSg3NDKW/zno8/aB 5/gGQF5TyOreDAy8Vr5fqT50k7RvyQ6C+KWholDxWErQEfgX02yEEu8uO6Pjoan9ezyk5h6xg2fSD bcxIFZ8rmX16D+1HsbQq6TkfyasZJ07otybHKckUOizAXJREiGc5dzytA2htrMlAHJWRSz5OsbkTZ rwM1K1+Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fTDGq-0006vF-V5; Wed, 13 Jun 2018 21:25:37 +0000 Received: from lilium.sigma-star.at ([109.75.188.150]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fTDFV-0004qK-Ha for linux-mtd@lists.infradead.org; Wed, 13 Jun 2018 21:24:17 +0000 Received: from localhost (localhost [127.0.0.1]) by lilium.sigma-star.at (Postfix) with ESMTP id A4792181B5049; Wed, 13 Jun 2018 23:24:00 +0200 (CEST) From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 01/14] ubi: fastmap: Read PEB numbers more carefully Date: Wed, 13 Jun 2018 23:23:31 +0200 Message-Id: <20180613212344.11608-2-richard@nod.at> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180613212344.11608-1-richard@nod.at> References: <20180613212344.11608-1-richard@nod.at> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180613_142413_937374_30B96F5D X-CRM114-Status: GOOD ( 14.72 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 T_SPF_PERMERROR SPF: test of record failed (permerror) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Weinberger , linux-kernel@vger.kernel.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org PEB numbers can be used as indices, make sure that they are within bounds. Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/fastmap.c | 71 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 462526a10537..768fa8a76867 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -101,6 +101,29 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi) return roundup(size, ubi->leb_size); } +static bool read_pnum(struct ubi_device *ubi, struct ubi_attach_info *ai, + __be32 pnum, int *out_pnum) +{ + int ret = true; + int max_pnum = ubi->peb_count; + + pnum = be32_to_cpu(pnum); + if (pnum == UBI_UNKNOWN) { + *out_pnum = pnum; + goto out; + } + + if (pnum < 0 || pnum >= max_pnum) { + ubi_err(ubi, "fastmap references PEB out of range: %i", pnum); + ret = false; + goto out; + } else { + *out_pnum = pnum; + } + +out: + return ret; +} /** * new_fm_vhdr - allocate a new volume header for fastmap usage. @@ -438,7 +461,10 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, int scrub = 0; int image_seq; - pnum = be32_to_cpu(pebs[i]); + if (!read_pnum(ubi, ai, pebs[i], &pnum)) { + ret = UBI_BAD_FASTMAP; + goto out; + } if (ubi_io_is_bad(ubi, pnum)) { ubi_err(ubi, "bad PEB in fastmap pool!"); @@ -565,7 +591,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, struct ubi_fm_ec *fmec; struct ubi_fm_volhdr *fmvhdr; struct ubi_fm_eba *fm_eba; - int ret, i, j, pool_size, wl_pool_size; + int ret, i, j, pool_size, wl_pool_size, pnum; size_t fm_pos = 0, fm_size = ubi->fm_size; unsigned long long max_sqnum = 0; void *fm_raw = ubi->fm_buf; @@ -647,8 +673,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 0); + if (!read_pnum(ubi, ai, fmec->pnum, &pnum)) + goto fail_bad; + + add_aeb(ai, &ai->free, pnum, be32_to_cpu(fmec->ec), 0); } /* read EC values from used list */ @@ -658,8 +686,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &used, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 0); + if (!read_pnum(ubi, ai, fmec->pnum, &pnum)) + goto fail_bad; + + add_aeb(ai, &used, pnum, be32_to_cpu(fmec->ec), 0); } /* read EC values from scrub list */ @@ -669,8 +699,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &used, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 1); + if (!read_pnum(ubi, ai, fmec->pnum, &pnum)) + goto fail_bad; + + add_aeb(ai, &used, pnum, be32_to_cpu(fmec->ec), 1); } /* read EC values from erase list */ @@ -680,8 +712,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 1); + if (!read_pnum(ubi, ai, fmec->pnum, &pnum)) + goto fail_bad; + + add_aeb(ai, &ai->erase, pnum, be32_to_cpu(fmec->ec), 1); } ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); @@ -731,7 +765,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, } for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) { - int pnum = be32_to_cpu(fm_eba->pnum[j]); + if (!read_pnum(ubi, ai, fm_eba->pnum[j], &pnum)) + goto fail_bad; if (pnum < 0) continue; @@ -954,7 +989,10 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, for (i = 0; i < used_blocks; i++) { int image_seq; - pnum = be32_to_cpu(fmsb->block_loc[i]); + if (!read_pnum(ubi, ai, fmsb->block_loc[i], &pnum)) { + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } if (ubi_io_is_bad(ubi, pnum)) { ret = UBI_BAD_FASTMAP; @@ -1068,7 +1106,14 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, goto free_hdr; } - e->pnum = be32_to_cpu(fmsb2->block_loc[i]); + if (!read_pnum(ubi, ai, fmsb2->block_loc[i], &e->pnum)) { + while (i--) + kmem_cache_free(ubi_wl_entry_slab, fm->e[i]); + + ret = -ENOMEM; + goto free_hdr; + } + e->ec = be32_to_cpu(fmsb2->block_ec[i]); fm->e[i] = e; }