Skip to content

Commit

Permalink
pcmcia: Fix resource leaks in yenta_probe() and _close()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Takeshi Yoshimura authored and Dominik Brodowski committed Jun 14, 2015
1 parent 2fb22a8 commit d19319a
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions drivers/pcmcia/yenta_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down Expand Up @@ -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;

/* error path... */
pcmcia_unregister_socket(&socket->socket);
}
if (ret)
goto free_irq;

/* 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;
}

Expand Down

0 comments on commit d19319a

Please sign in to comment.