pcmcia: Fix resource leaks in yenta_probe() and _close()

There are some resource leaks in yenta_probe() and _close(). I fixed
the following issues with some code cleanups. Thanks to Dominik's
suggestions.

On the error path in yenta_probe():
- a requested irq is not released
- yenta_free_resources() and pci_set_drvdata(dev, NULL) are not called

In yenta_close():
- kfree(sock) is not called
- sock->base is always set to non-NULL when yenta_close() is called,
  therefore the check in yenta_close() is not necessary.

Signed-off-by: Takeshi Yoshimura <yos@sslab.ics.keio.ac.jp>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Takeshi Yoshimura 2015-06-15 02:43:59 +09:00 коммит произвёл Dominik Brodowski
Родитель 2fb22a8042
Коммит d19319affb
1 изменённых файлов: 20 добавлений и 11 удалений

Просмотреть файл

@ -801,13 +801,13 @@ static void yenta_close(struct pci_dev *dev)
else
del_timer_sync(&sock->poll_timer);
if (sock->base)
iounmap(sock->base);
iounmap(sock->base);
yenta_free_resources(sock);
pci_release_regions(dev);
pci_disable_device(dev);
pci_set_drvdata(dev, NULL);
kfree(sock);
}
@ -1254,25 +1254,34 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Register it with the pcmcia layer.. */
ret = pcmcia_register_socket(&socket->socket);
if (ret == 0) {
/* Add the yenta register attributes */
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
if (ret == 0)
goto out;
if (ret)
goto free_irq;
/* error path... */
pcmcia_unregister_socket(&socket->socket);
}
/* Add the yenta register attributes */
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
if (ret)
goto unregister_socket;
return ret;
/* error path... */
unregister_socket:
pcmcia_unregister_socket(&socket->socket);
free_irq:
if (socket->cb_irq)
free_irq(socket->cb_irq, socket);
else
del_timer_sync(&socket->poll_timer);
unmap:
iounmap(socket->base);
yenta_free_resources(socket);
release:
pci_release_regions(dev);
disable:
pci_disable_device(dev);
free:
pci_set_drvdata(dev, NULL);
kfree(socket);
out:
return ret;
}