Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d19319af authored by Takeshi Yoshimura's avatar Takeshi Yoshimura Committed by Dominik Brodowski
Browse files

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: default avatarTakeshi Yoshimura <yos@sslab.ics.keio.ac.jp>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 2fb22a80
Loading
Loading
Loading
Loading
+21 −12
Original line number Original line Diff line number Diff line
@@ -801,13 +801,13 @@ static void yenta_close(struct pci_dev *dev)
	else
	else
		del_timer_sync(&sock->poll_timer);
		del_timer_sync(&sock->poll_timer);


	if (sock->base)
	iounmap(sock->base);
	iounmap(sock->base);
	yenta_free_resources(sock);
	yenta_free_resources(sock);


	pci_release_regions(dev);
	pci_release_regions(dev);
	pci_disable_device(dev);
	pci_disable_device(dev);
	pci_set_drvdata(dev, NULL);
	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.. */
	/* Register it with the pcmcia layer.. */
	ret = pcmcia_register_socket(&socket->socket);
	ret = pcmcia_register_socket(&socket->socket);
	if (ret == 0) {
	if (ret)
		goto free_irq;

	/* Add the yenta register attributes */
	/* Add the yenta register attributes */
	ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
	ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
		if (ret == 0)
	if (ret)
			goto out;
		goto unregister_socket;

	return ret;


	/* error path... */
	/* error path... */
 unregister_socket:
	pcmcia_unregister_socket(&socket->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:
 unmap:
	iounmap(socket->base);
	iounmap(socket->base);
	yenta_free_resources(socket);
 release:
 release:
	pci_release_regions(dev);
	pci_release_regions(dev);
 disable:
 disable:
	pci_disable_device(dev);
	pci_disable_device(dev);
 free:
 free:
	pci_set_drvdata(dev, NULL);
	kfree(socket);
	kfree(socket);
 out:
	return ret;
	return ret;
}
}