From patchwork Thu Apr 12 05:24:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 897484 X-Patchwork-Delegate: boris.brezillon@free-electrons.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.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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="J3r+K+zv"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kPks9H2+"; 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 40M8Wt65T4z9s1B for ; Thu, 12 Apr 2018 15:26:02 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version: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:In-Reply-To:References: List-Owner; bh=7Ts8AifQz06x0//9YsIbrr7WwyJPLrHg3L2zfPNSZFc=; b=J3r+K+zvt0Gvqf CwdTBK22FxUHbMXQ08b1sObyTI9/qHcDEsbdpOiqebm2h8PBpU8yXyxJpGIZ6gEPD2a/EBVU2qhlL YaqEPkegalHVW5E+O28bKuWKR5BUSI1y4l14B24+MH04fDs7+kcgUpl9mheGUcRku0rUAtTMcNuIr OIn5Kotta1vfXKcbbBoPQurJNrFa+f35OZxJaY5zhTW6ujMG/RlkPr1kZBt6B3g6EtTKfDLbLZMAQ CwIGFTI1j7FrOAWPFYpdqDMy4bYU0300ahuB9W3Bd8p9qGkCAx7HHAdRTQ43p+E5EfTcQ54eIQvEZ UYLY/7pqgKNiSjTcEScg==; 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 1f6Uk9-0004yv-9f; Thu, 12 Apr 2018 05:25:57 +0000 Received: from mail-lf0-x242.google.com ([2a00:1450:4010:c07::242]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1f6Uk5-0004xv-IO for linux-mtd@lists.infradead.org; Thu, 12 Apr 2018 05:25:55 +0000 Received: by mail-lf0-x242.google.com with SMTP id m200-v6so5820797lfm.4 for ; Wed, 11 Apr 2018 22:25:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=DQ2AM4Llc7GN6MB9FevwiENTKT7//DFQ/pj4XAZODZY=; b=kPks9H2+e27Ky3bYFysBXT/3tcKNCQnn9H6eEdMrHrJOQVTA8/VLPK62klMJZTBKmS mykKfGGyoWDe33i/Url+sY5Y5SZStTMoxfUams1GohlZYvqyenAB4uIEh/X+FOC2CdfD uJv2v3CAQVjRfhO6AX2qVu83WEa5qeKs+BZ5rdxphcV2kacButFAsAilZguo6U/8/njP Iz1V9lKZCHB+5g2httcWlGQgobDDEfbBnHr05UWOHosjyaHQ0GAUDhK7mXUPY4O5hODE x9+NjTA7OJJ0GWGGC40+pR3fy0yfC2CmFsq0SGOJ8Ytgn/4vU0VFBEAbbip+a29pS9BG eOLw== 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:mime-version :content-transfer-encoding; bh=DQ2AM4Llc7GN6MB9FevwiENTKT7//DFQ/pj4XAZODZY=; b=rwDzsFxd3U2zi1yuMywkWnZ+jMVElrhzkrLk6wBnSPIiK3L3PT2Ek3tScPG0Q1GX1B l463Q02Q5TPTeGr2pwyirUNGIhcl3CAUu+MGzNyvNfYfbvY4aefBar9Z/60ako9tyrTq 5J0qI7iNwuydxrVW9pGd+ZbTt/8HkcaRK5HpxzzB2wibzNBCGbFfq7DUunMuMm3ApuRJ 1G5bDzVrl7dUtXOQXYUPe2rFnKV+MuuPPqwEhu+S1DLlS1cQv1Il1SdyKoD3/flmfUhm 1hyS2Q8rLibJ05GjE2c24ALHQOcfzk9SbZ7xOQMbzKYEsHz1X97CUDTREDFhWbFArtF8 URxw== X-Gm-Message-State: ALQs6tCRYVaC+Uq6dENCQ7LPJ6JQnLRUsabpp7mZPh0xR3xC6CZi9qfD R98wa4SRhXjzWRYIG7Tu19WT2Q== X-Google-Smtp-Source: AIpwx49lC23sAaslWF3WKJWtQMVkB/J7mF1oBtpsDkh5P9jMsR9XUl75MDaLxcjMzZZoWVBuYw9PuA== X-Received: by 2002:a19:7904:: with SMTP id u4-v6mr4719672lfc.129.1523510741033; Wed, 11 Apr 2018 22:25:41 -0700 (PDT) Received: from linux-795u.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id r6sm453351ljr.4.2018.04.11.22.25.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 Apr 2018 22:25:39 -0700 (PDT) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: Brian Norris , David Woodhouse , Boris Brezillon , Marek Vasut , Richard Weinberger , Cyrille Pitchen Subject: [PATCH] mtd: bcm47xxpart: improve handling TRX partition size Date: Thu, 12 Apr 2018 07:24:52 +0200 Message-Id: <20180412052452.11498-1-zajec5@gmail.com> X-Mailer: git-send-email 2.12.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180411_222553_631554_8E94A270 X-CRM114-Status: GOOD ( 17.94 ) X-Spam-Score: -0.6 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:4010:c07:0:0:0:242 listed in] [list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (zajec5[at]gmail.com) 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (zajec5[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= , Hauke Mehrtens , linux-mtd@lists.infradead.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Rafał Miłecki When bcm47xxpart finds a TRX partition (container) it's supposed to jump to the end of it and keep looking for more partitions. TRX and its subpartitions are handled be a separated parser. The problem with old code was relying on the length specified in a TRX header. That isn't reliable as TRX is commonly modified to have checksum cover only non-changing subpartitions. Otherwise modifying e.g. a rootfs would result in CRC32 mismatch and bootloader refusing to boot a firmware. Fix it by trying better to figure out a real TRX size. We can securely assume that TRX has to cover all subpartitions and the last one is at least of a block size in size. Then compare it with a length field. This makes code more optimal & reliable thanks to skipping data that shouldn't be parsed. Signed-off-by: Rafał Miłecki --- drivers/mtd/bcm47xxpart.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index fe2581d9d882..1f0239848ebe 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -186,6 +186,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, /* TRX */ if (buf[0x000 / 4] == TRX_MAGIC) { struct trx_header *trx; + uint32_t last_subpart; + uint32_t trx_size; if (trx_num >= ARRAY_SIZE(trx_parts)) pr_warn("No enough space to store another TRX found at 0x%X\n", @@ -195,11 +197,23 @@ static int bcm47xxpart_parse(struct mtd_info *master, bcm47xxpart_add_part(&parts[curr_part++], "firmware", offset, 0); - /* Jump to the end of TRX */ + /* + * Try to find TRX size. The "length" field isn't fully + * reliable as it could be decreased to make CRC32 cover + * only part of TRX data. It's commonly used as checksum + * can't cover e.g. ever-changing rootfs partition. + * Use offsets as helpers for assuming min TRX size. + */ trx = (struct trx_header *)buf; - offset = roundup(offset + trx->length, blocksize); - /* Next loop iteration will increase the offset */ - offset -= blocksize; + last_subpart = max3(trx->offset[0], trx->offset[1], + trx->offset[2]); + trx_size = max(trx->length, last_subpart + blocksize); + + /* + * Skip the TRX data. Decrease offset by block size as + * the next loop iteration will increase it. + */ + offset += roundup(trx_size, blocksize) - blocksize; continue; }