Received: by 2002:a05:6a10:7420:0:0:0:0 with SMTP id hk32csp4428350pxb; Mon, 21 Feb 2022 21:18:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJxnsrhwy/BYsf3lm1qHgxR/KV5O8j0Kq7lYbzYIZQqEpZZwz7gae0bZI5GZRckootQWgPQB X-Received: by 2002:a17:902:f68b:b0:14f:c84c:ad6d with SMTP id l11-20020a170902f68b00b0014fc84cad6dmr5487673plg.155.1645507136891; Mon, 21 Feb 2022 21:18:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645507136; cv=none; d=google.com; s=arc-20160816; b=oFhnD1QK44VeR+CSKmumQRIHrAYNXB8pzeW5hJ5uLA78B8Q5PtonwrIjqZDaqGso76 sLoO2plMW+H+RjnAh9M7vJFF2HkwiwkMP1qMPMnILP+LPFJFANjnRIDjNeLvvlkubBeo BpU7VxRXK34xvwIdtBlbPZd/opP3HHODhV79BBv/WpB0vKK7C7Fss1u3GpGkGqU3LL0F IlT5cK99+2IUU7wgWrRNzFKd9juuXGDIhDbQcLYT/bj2XLZhjQSwhIAzEHw1ye3wJA/e AxwgFTwUyehIQbiY6sk/YasF9FGK1+ZjaJbwZrfNrFoCsnZfDbNRDOjVCwcR2493F564 dtVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=KM88VGbfW30tHu/yE6sInKC+hq+LN8iiMchF/oYkXIA=; b=PDAsGnf+UKnxwB88dRZUpNTaCxMXHE8McqVUuzJ2Waa3dGDPxSLHh9vvZlJG8dDIfc qjwf5u0hcoQDDSo0y+tC6BR/TLtjAPvU4WCDaBAwSa05mk2MWlBMQTbResIcWZ0Lnx9i at+a/d+kMPL0pQeiAt/teLZ95SulMY/aQPG/MRD32VIYnBo3yC5s2W6EXiTuXD3rfw7p yTDDm+jckSt9SpJWOJFHn0Aly0u4XEZ683OY8I9TwBqSZFfV51AgQ04fDvKe9FqqN+A9 vMr8+an/mwLFTSA9/fz1QMvIM+OmHZyoBoJQPLf3iTI+dRT8oSADul+wY7KL85cMPyyM lWNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=av8480uE; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id k21si15710588pll.131.2022.02.21.21.18.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Feb 2022 21:18:56 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=av8480uE; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BFE4CEEA6D; Mon, 21 Feb 2022 20:50:48 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353906AbiBUKCd (ORCPT + 99 others); Mon, 21 Feb 2022 05:02:33 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:57250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352328AbiBUJzK (ORCPT ); Mon, 21 Feb 2022 04:55:10 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23EF538792; Mon, 21 Feb 2022 01:24:09 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C600AB80EB9; Mon, 21 Feb 2022 09:24:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E8830C340E9; Mon, 21 Feb 2022 09:24:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1645435446; bh=kPsipjtm5BFbOtdKq1wVwjsC6HImBrZUVW4TMQmoygI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=av8480uENwpCN3B6p0CT0l9pk8bEliQvLFtrJz3JpQMoPtgCCx8gef4t3OTbsRJX6 PQtM1i5yuGRL0fLQ474LPdS9hmkk7Mcmbh+kSwAQ8aDcsGGBYINf99JdkCf32DnH13 BRAUnp0y+0KYP4Qc8WM83KI1cNXk9Ch0duTzkse8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ansuel Smith , Miquel Raynal Subject: [PATCH 5.16 166/227] mtd: parsers: qcom: Fix kernel panic on skipped partition Date: Mon, 21 Feb 2022 09:49:45 +0100 Message-Id: <20220221084940.343157397@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221084934.836145070@linuxfoundation.org> References: <20220221084934.836145070@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ansuel Smith commit 65d003cca335cabc0160d3cd7daa689eaa9dd3cd upstream. In the event of a skipped partition (case when the entry name is empty) the kernel panics in the cleanup function as the name entry is NULL. Rework the parser logic by first checking the real partition number and then allocate the space and set the data for the valid partitions. The logic was also fundamentally wrong as with a skipped partition, the parts number returned was incorrect by not decreasing it for the skipped partitions. Fixes: 803eb124e1a6 ("mtd: parsers: Add Qcom SMEM parser") Signed-off-by: Ansuel Smith Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220116032211.9728-1-ansuelsmth@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/parsers/qcomsmempart.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) --- a/drivers/mtd/parsers/qcomsmempart.c +++ b/drivers/mtd/parsers/qcomsmempart.c @@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mt const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { + size_t len = SMEM_FLASH_PTABLE_HDR_LEN; + int ret, i, j, tmpparts, numparts = 0; struct smem_flash_pentry *pentry; struct smem_flash_ptable *ptable; - size_t len = SMEM_FLASH_PTABLE_HDR_LEN; struct mtd_partition *parts; - int ret, i, numparts; char *name, *c; if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS) @@ -87,8 +87,8 @@ static int parse_qcomsmem_part(struct mt } /* Ensure that # of partitions is less than the max we have allocated */ - numparts = le32_to_cpu(ptable->numparts); - if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { + tmpparts = le32_to_cpu(ptable->numparts); + if (tmpparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { pr_err("Partition numbers exceed the max limit\n"); return -EINVAL; } @@ -116,11 +116,17 @@ static int parse_qcomsmem_part(struct mt return PTR_ERR(ptable); } + for (i = 0; i < tmpparts; i++) { + pentry = &ptable->pentry[i]; + if (pentry->name[0] != '\0') + numparts++; + } + parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); if (!parts) return -ENOMEM; - for (i = 0; i < numparts; i++) { + for (i = 0, j = 0; i < tmpparts; i++) { pentry = &ptable->pentry[i]; if (pentry->name[0] == '\0') continue; @@ -135,24 +141,25 @@ static int parse_qcomsmem_part(struct mt for (c = name; *c != '\0'; c++) *c = tolower(*c); - parts[i].name = name; - parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; - parts[i].mask_flags = pentry->attr; - parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; + parts[j].name = name; + parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; + parts[j].mask_flags = pentry->attr; + parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize; pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", i, pentry->name, le32_to_cpu(pentry->offset), le32_to_cpu(pentry->length), pentry->attr); + j++; } pr_debug("SMEM partition table found: ver: %d len: %d\n", - le32_to_cpu(ptable->version), numparts); + le32_to_cpu(ptable->version), tmpparts); *pparts = parts; return numparts; out_free_parts: - while (--i >= 0) - kfree(parts[i].name); + while (--j >= 0) + kfree(parts[j].name); kfree(parts); *pparts = NULL;