Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: da903x: fix use-after-free on unbind

Several MFD child drivers register their class devices directly under
the parent device. This means you cannot blindly do devres conversions
so that deregistration ends up being tied to the parent device,
something which leads to use-after-free on driver unbind when the class
device is released while still being registered.

Fixes: eed16255d66b ("leds: da903x: Use devm_led_classdev_register")
Cc: stable <stable@vger.kernel.org> # 4.6
Cc: Amitoj Kaur Chawla <amitoj1606@gmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Pavel Machek <pavel@ucw.cz>

authored by

Johan Hovold and committed by
Pavel Machek
6f4aa357 eca21c2d

+13 -1
+13 -1
drivers/leds/leds-da903x.c
··· 110 110 led->flags = pdata->flags; 111 111 led->master = pdev->dev.parent; 112 112 113 - ret = devm_led_classdev_register(led->master, &led->cdev); 113 + ret = led_classdev_register(led->master, &led->cdev); 114 114 if (ret) { 115 115 dev_err(&pdev->dev, "failed to register LED %d\n", id); 116 116 return ret; 117 117 } 118 + 119 + platform_set_drvdata(pdev, led); 120 + 121 + return 0; 122 + } 123 + 124 + static int da903x_led_remove(struct platform_device *pdev) 125 + { 126 + struct da903x_led *led = platform_get_drvdata(pdev); 127 + 128 + led_classdev_unregister(&led->cdev); 118 129 119 130 return 0; 120 131 } ··· 135 124 .name = "da903x-led", 136 125 }, 137 126 .probe = da903x_led_probe, 127 + .remove = da903x_led_remove, 138 128 }; 139 129 140 130 module_platform_driver(da903x_led_driver);