From patchwork Thu Sep 7 09:00:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gilad Ben-Yossef X-Patchwork-Id: 111871 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp516878qge; Thu, 7 Sep 2017 02:01:41 -0700 (PDT) X-Google-Smtp-Source: ADKCNb4J4YmrT63sCJICJQcxRZEdnKLoYDAYOUsbl1+XBUcXuFMiooUWQJmLM4Joi+F54vI4jWy8 X-Received: by 10.99.116.21 with SMTP id p21mr1990532pgc.93.1504774901000; Thu, 07 Sep 2017 02:01:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504774900; cv=none; d=google.com; s=arc-20160816; b=kIUYuv5hZ1V07KnCBHCPiRpTzSiif/t2GrpppJr5SQLApznB1w4M7XrvI2mc+IgVzx SEobcQmvhcaAPhB+yAZqNLI9E9HLt59B6RckIQ3Q9K89m1y5opUPuLnQQnoJHvtvaaKe QnBPyj6eR8oCiuJE8fZwlY9ufF3vxJCn6X/49zLfMN7R/MhEItFCESObJQj2aQM5T4Vt 51Wt1OqwUgNwDIgj0SAwNSwGszFi/tb936/9B8tYP8upQxCU2F6mTCJcScV7G57UcmBS Arz943T0TrtKxu5nphCOEsYuzKLnc/WHN5cbuPjLXtJvGbBCb2sGX2yQwVX/SPPTWudk Ckpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=piDruKUdB/WtbXjqG68v1yNY2cEQwEm8f0l8ijoz5yI=; b=lrs9iwqpU/c8A3j7D3kc6T4t0rjaf/Xt+Ran8GvBGMlfXMUVAtIExoDIV+CB7LIL/t awfEecSwJVYBHBhFXam5V1l+wo1Mp2TQQpjhBox7sQlUMxCtSL+5F20YQKXUO9o4k1KS qWhXP9efupMvB9TMpft8d7kw/FKNdR4uA9R0QnPZLT3nfH8W7zx+WV1CeYmm58r8wFR3 grGCTUTCFClwrLvl8VswOW8Zf2KKDuxKAtB5k8kGhpela70W7JZxcyJEQ4XG+/N/BYlg kPE5v40TyaZPURjz8MYpLAe/F0ErYeFAMsosx5DzTZeDF6kGbjnv5fwj3t4/nVWnKhYq W9bA== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a2si1648903pln.695.2017.09.07.02.01.40; Thu, 07 Sep 2017 02:01:40 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755001AbdIGJBi (ORCPT + 26 others); Thu, 7 Sep 2017 05:01:38 -0400 Received: from foss.arm.com ([217.140.101.70]:57256 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754931AbdIGJBg (ORCPT ); Thu, 7 Sep 2017 05:01:36 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6627180D; Thu, 7 Sep 2017 02:01:36 -0700 (PDT) Received: from gby.kfn.arm.com (unknown [10.45.48.140]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 88AEF3F540; Thu, 7 Sep 2017 02:01:34 -0700 (PDT) From: Gilad Ben-Yossef To: Greg Kroah-Hartman , linux-crypto@vger.kernel.org, driverdev-devel@linuxdriverproject.org, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org Cc: Ofir Drang Subject: [PATCH v3 4/8] staging: ccree: simplify resource release on error Date: Thu, 7 Sep 2017 12:00:12 +0300 Message-Id: <1504774817-11984-5-git-send-email-gilad@benyossef.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1504774817-11984-1-git-send-email-gilad@benyossef.com> References: <1504774817-11984-1-git-send-email-gilad@benyossef.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The resource release on probe/init error was being handled in an awkward manner and possibly leaking memory on certain (unlikely) error path. Fix it by simplifying the error resource release and making it easier to track. Reported-by: Dan Carpenter Signed-off-by: Gilad Ben-Yossef --- drivers/staging/ccree/ssi_aead.c | 3 +- drivers/staging/ccree/ssi_cipher.c | 3 +- drivers/staging/ccree/ssi_driver.c | 102 ++++++++++++++++++++----------------- drivers/staging/ccree/ssi_hash.c | 3 +- 4 files changed, 59 insertions(+), 52 deletions(-) -- 2.1.4 diff --git a/drivers/staging/ccree/ssi_aead.c b/drivers/staging/ccree/ssi_aead.c index 5abe6b2..8191ec4 100644 --- a/drivers/staging/ccree/ssi_aead.c +++ b/drivers/staging/ccree/ssi_aead.c @@ -2720,6 +2720,7 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) goto fail0; } + INIT_LIST_HEAD(&aead_handle->aead_list); drvdata->aead_handle = aead_handle; aead_handle->sram_workspace_addr = ssi_sram_mgr_alloc( @@ -2730,8 +2731,6 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) goto fail1; } - INIT_LIST_HEAD(&aead_handle->aead_list); - /* Linux crypto */ for (alg = 0; alg < ARRAY_SIZE(aead_algs); alg++) { t_alg = ssi_aead_create_alg(&aead_algs[alg]); diff --git a/drivers/staging/ccree/ssi_cipher.c b/drivers/staging/ccree/ssi_cipher.c index 1ff3c8a..ab0349f 100644 --- a/drivers/staging/ccree/ssi_cipher.c +++ b/drivers/staging/ccree/ssi_cipher.c @@ -1312,9 +1312,8 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata) if (!ablkcipher_handle) return -ENOMEM; - drvdata->blkcipher_handle = ablkcipher_handle; - INIT_LIST_HEAD(&ablkcipher_handle->blkcipher_alg_list); + drvdata->blkcipher_handle = ablkcipher_handle; /* Linux crypto */ SSI_LOG_DEBUG("Number of algorithms = %zu\n", ARRAY_SIZE(blkcipher_algs)); diff --git a/drivers/staging/ccree/ssi_driver.c b/drivers/staging/ccree/ssi_driver.c index 3e7193d..dc22f13 100644 --- a/drivers/staging/ccree/ssi_driver.c +++ b/drivers/staging/ccree/ssi_driver.c @@ -233,16 +233,14 @@ static int init_cc_resources(struct platform_device *plat_dev) if (!new_drvdata) { SSI_LOG_ERR("Failed to allocate drvdata"); rc = -ENOMEM; - goto init_cc_res_err; + goto post_drvdata_err; } + dev_set_drvdata(&plat_dev->dev, new_drvdata); + new_drvdata->plat_dev = plat_dev; new_drvdata->clk = of_clk_get(np, 0); new_drvdata->coherent = of_dma_is_coherent(np); - /*Initialize inflight counter used in dx_ablkcipher_secure_complete used for count of BYSPASS blocks operations*/ - new_drvdata->inflight_counter = 0; - - dev_set_drvdata(&plat_dev->dev, new_drvdata); /* Get device resources */ /* First CC registers space */ req_mem_cc_regs = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); @@ -250,38 +248,42 @@ static int init_cc_resources(struct platform_device *plat_dev) new_drvdata->cc_base = devm_ioremap_resource(&plat_dev->dev, req_mem_cc_regs); if (IS_ERR(new_drvdata->cc_base)) { + SSI_LOG_ERR("Failed to ioremap registers"); rc = PTR_ERR(new_drvdata->cc_base); - goto init_cc_res_err; + goto post_drvdata_err; } + SSI_LOG_DEBUG("Got MEM resource (%s): start=%pad end=%pad\n", req_mem_cc_regs->name, req_mem_cc_regs->start, req_mem_cc_regs->end); SSI_LOG_DEBUG("CC registers mapped from %pa to 0x%p\n", &req_mem_cc_regs->start, new_drvdata->cc_base); + cc_base = new_drvdata->cc_base; + /* Then IRQ */ new_drvdata->irq = platform_get_irq(plat_dev, 0); if (new_drvdata->irq < 0) { SSI_LOG_ERR("Failed getting IRQ resource\n"); rc = new_drvdata->irq; - goto init_cc_res_err; + goto post_drvdata_err; } + rc = devm_request_irq(&plat_dev->dev, new_drvdata->irq, cc_isr, IRQF_SHARED, "arm_cc7x", new_drvdata); if (rc) { SSI_LOG_ERR("Could not register to interrupt %d\n", new_drvdata->irq); - goto init_cc_res_err; + goto post_drvdata_err; } - init_completion(&new_drvdata->icache_setup_completion); - SSI_LOG_DEBUG("Registered to IRQ: %d\n", new_drvdata->irq); - new_drvdata->plat_dev = plat_dev; + + init_completion(&new_drvdata->icache_setup_completion); rc = cc_clk_on(new_drvdata); if (rc) - goto init_cc_res_err; + goto post_drvdata_err; if (!new_drvdata->plat_dev->dev.dma_mask) new_drvdata->plat_dev->dev.dma_mask = &new_drvdata->plat_dev->dev.coherent_dma_mask; @@ -295,7 +297,7 @@ static int init_cc_resources(struct platform_device *plat_dev) SSI_LOG_ERR("Invalid CC signature: SIGNATURE=0x%08X != expected=0x%08X\n", signature_val, (u32)DX_DEV_SIGNATURE); rc = -EINVAL; - goto init_cc_res_err; + goto post_clk_err; } SSI_LOG_DEBUG("CC SIGNATURE=0x%08X\n", signature_val); @@ -306,21 +308,26 @@ static int init_cc_resources(struct platform_device *plat_dev) rc = init_cc_regs(new_drvdata, true); if (unlikely(rc != 0)) { SSI_LOG_ERR("init_cc_regs failed\n"); - goto init_cc_res_err; + goto post_clk_err; } #ifdef ENABLE_CC_SYSFS rc = ssi_sysfs_init(&plat_dev->dev.kobj, new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("init_stat_db failed\n"); - goto init_cc_res_err; + goto post_regs_err; } #endif + rc = ssi_fips_init(new_drvdata); + if (unlikely(rc != 0)) { + SSI_LOG_ERR("SSI_FIPS_INIT failed 0x%x\n", rc); + goto post_sysfs_err; + } rc = ssi_sram_mgr_init(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_sram_mgr_init failed\n"); - goto init_cc_res_err; + goto post_fips_init_err; } new_drvdata->mlli_sram_addr = @@ -328,57 +335,51 @@ static int init_cc_resources(struct platform_device *plat_dev) if (unlikely(new_drvdata->mlli_sram_addr == NULL_SRAM_ADDR)) { SSI_LOG_ERR("Failed to alloc MLLI Sram buffer\n"); rc = -ENOMEM; - goto init_cc_res_err; + goto post_sram_mgr_err; } rc = request_mgr_init(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("request_mgr_init failed\n"); - goto init_cc_res_err; + goto post_sram_mgr_err; } rc = ssi_buffer_mgr_init(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("buffer_mgr_init failed\n"); - goto init_cc_res_err; + goto post_req_mgr_err; } rc = ssi_power_mgr_init(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_power_mgr_init failed\n"); - goto init_cc_res_err; - } - - rc = ssi_fips_init(new_drvdata); - if (unlikely(rc != 0)) { - SSI_LOG_ERR("SSI_FIPS_INIT failed 0x%x\n", rc); - goto init_cc_res_err; + goto post_buf_mgr_err; } rc = ssi_ivgen_init(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_ivgen_init failed\n"); - goto init_cc_res_err; + goto post_power_mgr_err; } /* Allocate crypto algs */ rc = ssi_ablkcipher_alloc(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_ablkcipher_alloc failed\n"); - goto init_cc_res_err; + goto post_ivgen_err; } /* hash must be allocated before aead since hash exports APIs */ rc = ssi_hash_alloc(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_hash_alloc failed\n"); - goto init_cc_res_err; + goto post_cipher_err; } rc = ssi_aead_alloc(new_drvdata); if (unlikely(rc != 0)) { SSI_LOG_ERR("ssi_aead_alloc failed\n"); - goto init_cc_res_err; + goto post_hash_err; } /* If we got here and FIPS mode is enabled @@ -389,24 +390,33 @@ static int init_cc_resources(struct platform_device *plat_dev) return 0; -init_cc_res_err: - SSI_LOG_ERR("Freeing CC HW resources!\n"); - - if (new_drvdata) { - ssi_aead_free(new_drvdata); - ssi_hash_free(new_drvdata); - ssi_ablkcipher_free(new_drvdata); - ssi_ivgen_fini(new_drvdata); - ssi_power_mgr_fini(new_drvdata); - ssi_buffer_mgr_fini(new_drvdata); - request_mgr_fini(new_drvdata); - ssi_sram_mgr_fini(new_drvdata); - ssi_fips_fini(new_drvdata); +post_hash_err: + ssi_hash_free(new_drvdata); +post_cipher_err: + ssi_ablkcipher_free(new_drvdata); +post_ivgen_err: + ssi_ivgen_fini(new_drvdata); +post_power_mgr_err: + ssi_power_mgr_fini(new_drvdata); +post_buf_mgr_err: + ssi_buffer_mgr_fini(new_drvdata); +post_req_mgr_err: + request_mgr_fini(new_drvdata); +post_sram_mgr_err: + ssi_sram_mgr_fini(new_drvdata); +post_fips_init_err: + ssi_fips_fini(new_drvdata); +post_sysfs_err: #ifdef ENABLE_CC_SYSFS - ssi_sysfs_fini(); + ssi_sysfs_fini(); #endif - dev_set_drvdata(&plat_dev->dev, NULL); - } +post_regs_err: + fini_cc_regs(new_drvdata); +post_clk_err: + cc_clk_off(new_drvdata); +post_drvdata_err: + SSI_LOG_ERR("ccree init error occurred!\n"); + dev_set_drvdata(&plat_dev->dev, NULL); return rc; } diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/ssi_hash.c index 13291ae..36495b5 100644 --- a/drivers/staging/ccree/ssi_hash.c +++ b/drivers/staging/ccree/ssi_hash.c @@ -2234,6 +2234,7 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) goto fail; } + INIT_LIST_HEAD(&hash_handle->hash_list); drvdata->hash_handle = hash_handle; sram_size_to_alloc = sizeof(digest_len_init) + @@ -2264,8 +2265,6 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) goto fail; } - INIT_LIST_HEAD(&hash_handle->hash_list); - /* ahash registration */ for (alg = 0; alg < ARRAY_SIZE(driver_hash); alg++) { struct ssi_hash_alg *t_alg;