Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753063AbbGAVXd (ORCPT ); Wed, 1 Jul 2015 17:23:33 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42531 "EHLO mail.ispras.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752770AbbGAVX1 (ORCPT ); Wed, 1 Jul 2015 17:23:27 -0400 From: Alexey Khoroshilov To: Neil Brown , Jens Axboe Cc: Alexey Khoroshilov , linux-kernel@vger.kernel.org, ldv-project@linuxtesting.org Subject: [PATCH] umem: don't return zero on failure paths in mm_pci_probe() Date: Thu, 2 Jul 2015 00:23:09 +0300 Message-Id: <1435785789-9912-1-git-send-email-khoroshilov@ispras.ru> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3237 Lines: 100 If pci_alloc_consistent() or blk_alloc_queue() failed, mm_pci_probe() breaks off initialization, deallocates resources, but returns zero. The patch adds -ENOMEM as a return value in these cases. By the way, it adds blk_cleanup_queue() and pci_disable_device() to fix leaks in failure handling code. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/block/umem.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 4cf81b5bf0f7..960a3cadcd6b 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -808,12 +808,14 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF8); pci_set_master(dev); - card->dev = dev; + card->dev = dev; csr_base = pci_resource_start(dev, 0); csr_len = pci_resource_len(dev, 0); - if (!csr_base || !csr_len) - return -ENODEV; + if (!csr_base || !csr_len) { + ret = -ENODEV; + goto failed_pci; + } dev_printk(KERN_INFO, &dev->dev, "Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n"); @@ -821,7 +823,8 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (pci_set_dma_mask(dev, DMA_BIT_MASK(64)) && pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { dev_printk(KERN_WARNING, &dev->dev, "NO suitable DMA found\n"); - return -ENOMEM; + ret = -ENOMEM; + goto failed_pci; } ret = pci_request_regions(dev, DRIVER_NAME); @@ -836,7 +839,6 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_printk(KERN_ERR, &card->dev->dev, "Unable to remap memory region\n"); ret = -ENOMEM; - goto failed_remap_csr; } @@ -881,6 +883,7 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (card->mm_pages[0].desc == NULL || card->mm_pages[1].desc == NULL) { dev_printk(KERN_ERR, &card->dev->dev, "alloc failed\n"); + ret = -ENOMEM; goto failed_alloc; } reset_page(&card->mm_pages[0]); @@ -891,8 +894,10 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) card->biotail = &card->bio; card->queue = blk_alloc_queue(GFP_KERNEL); - if (!card->queue) + if (!card->queue) { + ret = -ENOMEM; goto failed_alloc; + } blk_queue_make_request(card->queue, mm_make_request); card->queue->queue_lock = &card->lock; @@ -1002,6 +1007,7 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; failed_req_irq: + blk_cleanup_queue(card->queue); failed_alloc: if (card->mm_pages[0].desc) pci_free_consistent(card->dev, PAGE_SIZE*2, @@ -1016,6 +1022,8 @@ static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) failed_remap_csr: pci_release_regions(dev); failed_req_csr: + failed_pci: + pci_disable_device(dev); return ret; } -- 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/