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

Commit 05731b97 authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Linus Torvalds
Browse files

rtc/mc13783: fix use after free bug



This was introduced by v2.6.34-rc1~38:

	4c014e87 (rtc/mc13783: protect rtc {,un}registration by mc13783 lock)

Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reported-by: default avatarDan Carpenter <error27@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e7bbcdf3
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -319,35 +319,38 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
{
	int ret;
	struct mc13783_rtc *priv;
	struct mc13783 *mc13783;
	int rtcrst_pending;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
	mc13783 = dev_get_drvdata(pdev->dev.parent);
	priv->mc13783 = mc13783;

	platform_set_drvdata(pdev, priv);

	mc13783_lock(priv->mc13783);
	mc13783_lock(mc13783);

	ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
	ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST,
			mc13783_rtc_reset_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_reset_irq_request;

	ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_RTCRST,
	ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST,
			NULL, &rtcrst_pending);
	if (ret)
		goto err_reset_irq_status;

	priv->valid = !rtcrst_pending;

	ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
	ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ,
			mc13783_rtc_update_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_update_irq_request;

	ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_TODA,
	ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA,
			mc13783_rtc_alarm_handler, DRIVER_NAME, priv);
	if (ret)
		goto err_alarm_irq_request;
@@ -357,22 +360,22 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
	if (IS_ERR(priv->rtc)) {
		ret = PTR_ERR(priv->rtc);

		mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
		mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv);
err_alarm_irq_request:

		mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
		mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv);
err_update_irq_request:

err_reset_irq_status:

		mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
		mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv);
err_reset_irq_request:

		platform_set_drvdata(pdev, NULL);
		kfree(priv);
	}

	mc13783_unlock(priv->mc13783);
	mc13783_unlock(mc13783);

	return ret;
}