Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753952AbbFRBDG (ORCPT ); Wed, 17 Jun 2015 21:03:06 -0400 Received: from mail-pd0-f173.google.com ([209.85.192.173]:36402 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751633AbbFRBCz (ORCPT ); Wed, 17 Jun 2015 21:02:55 -0400 From: Gregory Fong To: linux-gpio@vger.kernel.org Cc: Gregory Fong , Alexandre Courbot , bcm-kernel-feedback-list@broadcom.com, Brian Norris , devicetree@vger.kernel.org, Florian Fainelli , Ian Campbell , Kumar Gala , Linus Walleij , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Mark Rutland , Pawel Moll , Rob Herring , Russell King Subject: [PATCH v3 1/4] gpio: brcmstb: fix null ptr dereference in driver remove Date: Wed, 17 Jun 2015 18:00:40 -0700 Message-Id: <1434589243-502-2-git-send-email-gregory.0xf0@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434589243-502-1-git-send-email-gregory.0xf0@gmail.com> References: <1434589243-502-1-git-send-email-gregory.0xf0@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2480 Lines: 71 If a failure occurs during probe, brcmstb_gpio_remove() is called. In remove, we call platform_get_drvdata(), but at the time of failure in the probe the driver data hadn't yet been set which leads to a NULL ptr dereference in the remove's list_for_each. Call platform_set_drvdata() and set up list head right after allocating the priv struct to both avoid the null pointer dereference that could occur today. To guard against potential future changes, check for null pointer in remove. Reported-by: Tim Ross Signed-off-by: Gregory Fong --- New in v3. drivers/gpio/gpio-brcmstb.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 7a3cb1f..4630a81 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -87,6 +87,15 @@ static int brcmstb_gpio_remove(struct platform_device *pdev) struct brcmstb_gpio_bank *bank; int ret = 0; + if (!priv) { + dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); + return -EFAULT; + } + + /* + * You can lose return values below, but we report all errors, and it's + * more important to actually perform all of the steps. + */ list_for_each(pos, &priv->bank_list) { bank = list_entry(pos, struct brcmstb_gpio_bank, node); ret = bgpio_remove(&bank->bgc); @@ -143,6 +152,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + platform_set_drvdata(pdev, priv); + INIT_LIST_HEAD(&priv->bank_list); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg_base = devm_ioremap_resource(dev, res); @@ -153,7 +164,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) priv->reg_base = reg_base; priv->pdev = pdev; - INIT_LIST_HEAD(&priv->bank_list); if (brcmstb_gpio_sanity_check_banks(dev, np, res)) return -EINVAL; @@ -221,8 +231,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", priv->num_banks, priv->gpio_base, gpio_base - 1); - platform_set_drvdata(pdev, priv); - return 0; fail: -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/