Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp1101060rwb; Sun, 18 Sep 2022 00:11:29 -0700 (PDT) X-Google-Smtp-Source: AMsMyM52msFx/P8aU3ofIAouslsuJC1s+zY0jAGICOS9Yvg1VOZeiNpjzFnrF7VOwqURSl2Hv5mq X-Received: by 2002:a17:906:dc8a:b0:781:3f5a:52c3 with SMTP id cs10-20020a170906dc8a00b007813f5a52c3mr690222ejc.5.1663485089289; Sun, 18 Sep 2022 00:11:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663485089; cv=none; d=google.com; s=arc-20160816; b=qykjRF6uaz1F+FdeSi8ZdxoeS618363aqRk2zIbalw5Td6HF4YrVZXIRiaBaMlizQx j10OdBdlP+dR457GFI4ipYZqI8bHc3+lYMPxfySSeV7BOdjfev9Cd2UqaWTuNHmLS+wl RwtDmE2gBXrx9Qezdhufd7V6zIgDxdEIUfGJkskdVoTDQQG5BiN78C/wzAQ/3OKdQk3b pmoUuHWMjPkiBgIJthWX+jTzOqQh0KLsJIBo4XnHGpoUh+JmZeerJ07FSQ3+z/rwbVnQ WErETjOeR8KLIlcauqZlnQ+W+S3ztXsyJFOMUBFzSeU81v8bpe8/QtWxdSwr71ecItoA gsFQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=htoi00SyvsU5D7bh9OQKGgfkjHpCJ/fdOcsSqnQ7Mm0=; b=GtWySaMjIF07bkTXWI5V88h67PkWKwm0dqsVuI5v9ynY9+fsMQNxfLf4W3z6B21+c5 9BRnDZbjlfAJfGqKFVi+/bfVw1PvlJja2suO99QUnEwXs5DXyTJSyZBb5J5buPhZPDa/ 5GKLUnanWwelqRkweTsmRvY8bh5reOg5wS8+R6JW8Msz4/k7yVdUSrOKCnizJTGG8fov OL3nZesNZm5f62RN9rKd8Jf0axuSnUfpp1tFZ8k2TaILpD7pSHrrR/hPooOgZwPkWirx sgy7Jqa7ZCJfk7HmSJQYlwbt98SvjUu66LN1GhKZ3o4Rvm1R39SALQwVz4S3/5aJf1pq 2PCw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id xj1-20020a170906db0100b00780a7ebc522si6656641ejb.596.2022.09.18.00.10.56; Sun, 18 Sep 2022 00:11:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229457AbiIRG2A (ORCPT + 99 others); Sun, 18 Sep 2022 02:28:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229447AbiIRG1u (ORCPT ); Sun, 18 Sep 2022 02:27:50 -0400 Received: from smtp.smtpout.orange.fr (smtp04.smtpout.orange.fr [80.12.242.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DB5D2611F for ; Sat, 17 Sep 2022 23:27:47 -0700 (PDT) Received: from pop-os.home ([90.11.190.129]) by smtp.orange.fr with ESMTPA id ZnmJo9OZsAOp2ZnmJoqqJY; Sun, 18 Sep 2022 08:27:45 +0200 X-ME-Helo: pop-os.home X-ME-Auth: Y2hyaXN0b3BoZS5qYWlsbGV0QHdhbmFkb28uZnI= X-ME-Date: Sun, 18 Sep 2022 08:27:45 +0200 X-ME-IP: 90.11.190.129 From: Christophe JAILLET To: Kumaravel Thiagarajan , Arnd Bergmann , Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org, Christophe JAILLET , linux-gpio@vger.kernel.org Subject: [PATCH 3/3] misc: microchip: pci1xxxx: Fix the error handling paths of gp_aux_bus_probe() Date: Sun, 18 Sep 2022 08:27:42 +0200 Message-Id: <1b41531de02ee029628d9b0ec2cf1ee7f180fe10.1663482259.git.christophe.jaillet@wanadoo.fr> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=unavailable 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 There are several issues related to the error handling paths of gp_aux_bus_probe(): - some resources may be released twice. Once explicitly in the error handling path, and once via the release() function - auxiliary_device_delete() should be called after the first successful auxiliary_device_add() To fix them, reorder the code: - move the place where we get the irq for the 2nd wrapper. - call kfree() and ida_free() after error checks, rather then in the error handling path. - have the error handling path look like the remove function Fixes: 393fc2f5948f ("misc: microchip: pci1xxxx: load auxiliary bus driver for the PIO function in the multi-function endpoint of pci1xxxx device.") Signed-off-by: Christophe JAILLET --- This patch is speculative and untested, review with care. Other solutions are possible. For example, we could use devm_kzalloc() to simplify the error handling path and the release function. --- drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c index 32af2b14ff34..d3253e98f2ec 100644 --- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c +++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c @@ -32,7 +32,7 @@ static void gp_auxiliary_device_release(struct device *dev) static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct aux_bus_device *aux_bus; - int retval; + int irq, retval; retval = pcim_enable_device(pdev); if (retval) @@ -48,8 +48,10 @@ static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id return -ENOMEM; retval = ida_alloc(&gp_client_ida, GFP_KERNEL); - if (retval < 0) - goto err_ida_alloc_0; + if (retval < 0) { + kfree(aux_bus->aux_device_wrapper[0]); + return retval; + } aux_bus->aux_device_wrapper[0]->aux_dev.name = aux_dev_otp_e2p_name; aux_bus->aux_device_wrapper[0]->aux_dev.dev.parent = &pdev->dev; @@ -60,21 +62,38 @@ static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id aux_bus->aux_device_wrapper[0]->gp_aux_data.region_length = pci_resource_end(pdev, 0); retval = auxiliary_device_init(&aux_bus->aux_device_wrapper[0]->aux_dev); - if (retval < 0) - goto err_aux_dev_init_0; + if (retval < 0) { + ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[0]->aux_dev.id); + kfree(aux_bus->aux_device_wrapper[0]); + goto err_aux_dev_uninit_0; + } retval = auxiliary_device_add(&aux_bus->aux_device_wrapper[0]->aux_dev); if (retval) - goto err_aux_dev_add_0; + goto err_aux_dev_uninit_0; + + + retval = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (retval < 0) + goto err_aux_dev_del_0; + + retval = pci_irq_vector(pdev, 0); + if (retval < 0) + goto err_aux_dev_del_0; + irq = retval; aux_bus->aux_device_wrapper[1] = kzalloc(sizeof(*aux_bus->aux_device_wrapper[1]), GFP_KERNEL); - if (!aux_bus->aux_device_wrapper[1]) - return -ENOMEM; + if (!aux_bus->aux_device_wrapper[1]) { + retval = -ENOMEM; + goto err_aux_dev_del_0; + } retval = ida_alloc(&gp_client_ida, GFP_KERNEL); - if (retval < 0) - goto err_ida_alloc_1; + if (retval < 0) { + kfree(aux_bus->aux_device_wrapper[1]); + goto err_aux_dev_del_0; + } aux_bus->aux_device_wrapper[1]->aux_dev.name = aux_dev_gpio_name; aux_bus->aux_device_wrapper[1]->aux_dev.dev.parent = &pdev->dev; @@ -84,49 +103,34 @@ static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id aux_bus->aux_device_wrapper[1]->gp_aux_data.region_start = pci_resource_start(pdev, 0); aux_bus->aux_device_wrapper[1]->gp_aux_data.region_length = pci_resource_end(pdev, 0); - retval = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); - - if (retval < 0) - goto err_aux_dev_init_1; - - retval = pci_irq_vector(pdev, 0); - if (retval < 0) - goto err_aux_dev_init_1; - pdev->irq = retval; aux_bus->aux_device_wrapper[1]->gp_aux_data.irq_num = pdev->irq; retval = auxiliary_device_init(&aux_bus->aux_device_wrapper[1]->aux_dev); - if (retval < 0) - goto err_aux_dev_init_1; + if (retval < 0) { + ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[1]->aux_dev.id); + kfree(aux_bus->aux_device_wrapper[1]); + goto err_aux_dev_del_0; + } retval = auxiliary_device_add(&aux_bus->aux_device_wrapper[1]->aux_dev); if (retval) - goto err_aux_dev_add_1; + goto err_aux_dev_uninit_1; pci_set_drvdata(pdev, aux_bus); pci_set_master(pdev); return 0; -err_aux_dev_add_1: +err_aux_dev_uninit_1: auxiliary_device_uninit(&aux_bus->aux_device_wrapper[1]->aux_dev); -err_aux_dev_init_1: - ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[1]->aux_dev.id); - -err_ida_alloc_1: - kfree(aux_bus->aux_device_wrapper[1]); +err_aux_dev_del_0: + auxiliary_device_delete(&aux_bus->aux_device_wrapper[0]->aux_dev); -err_aux_dev_add_0: +err_aux_dev_uninit_0: auxiliary_device_uninit(&aux_bus->aux_device_wrapper[0]->aux_dev); -err_aux_dev_init_0: - ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[0]->aux_dev.id); - -err_ida_alloc_0: - kfree(aux_bus->aux_device_wrapper[0]); - return retval; } -- 2.34.1