Commit 8265d06b authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

USB: appledisplay: close race between probe and completion handler



There is a small window during probing when IO is running
but the backlight is not registered. Processing events
during that time will crash. The completion handler
needs to check for a backlight before scheduling work.

The bug is as old as the driver.

Signed-off-by: default avatarOliver Neukum <oneukum@suse.com>
CC: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240912123317.1026049-1-oneukum@suse.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b41c1fa1
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -107,6 +107,11 @@ static void appledisplay_complete(struct urb *urb)
	case ACD_BTN_BRIGHT_UP:
	case ACD_BTN_BRIGHT_DOWN:
		pdata->button_pressed = 1;
		/*
		 * there is a window during which no device
		 * is registered
		 */
		if (pdata->bd )
			schedule_delayed_work(&pdata->work, 0);
		break;
	case ACD_BTN_NONE:
@@ -202,6 +207,7 @@ static int appledisplay_probe(struct usb_interface *iface,
	const struct usb_device_id *id)
{
	struct backlight_properties props;
	struct backlight_device *backlight;
	struct appledisplay *pdata;
	struct usb_device *udev = interface_to_usbdev(iface);
	struct usb_endpoint_descriptor *endpoint;
@@ -272,13 +278,14 @@ static int appledisplay_probe(struct usb_interface *iface,
	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = 0xff;
	pdata->bd = backlight_device_register(bl_name, NULL, pdata,
	backlight = backlight_device_register(bl_name, NULL, pdata,
					      &appledisplay_bl_data, &props);
	if (IS_ERR(pdata->bd)) {
	if (IS_ERR(backlight)) {
		dev_err(&iface->dev, "Backlight registration failed\n");
		retval = PTR_ERR(pdata->bd);
		retval = PTR_ERR(backlight);
		goto error;
	}
	pdata->bd = backlight;

	/* Try to get brightness */
	brightness = appledisplay_bl_get_brightness(pdata->bd);