Commit 1d1b564f authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Jiri Kosina

hid: thingm: reorder calls in thingm_probe

When reviewing another thingm patch Benjamin Tissoires pointed out
the following: "The problem here is that hid_hw_start() is called
before thingm_version() which allows user space to briefly introduce
races between thingm_version() and any hidraw requests.
The mutex will not help here as it is initialized after hid_hw_start()
and only used for protecting the concurrent access of the rgb."

Avoid this possible issue by calling hid_hw_start() later in the
probe function.
Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 43a4a04d
...@@ -216,17 +216,13 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -216,17 +216,13 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
err = hid_parse(hdev); err = hid_parse(hdev);
if (err) if (err)
goto error; return err;
err = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
if (err)
goto error;
mutex_init(&tdev->lock); mutex_init(&tdev->lock);
err = thingm_version(tdev); err = thingm_version(tdev);
if (err) if (err)
goto stop; return err;
hid_dbg(hdev, "firmware version: %c.%c\n", hid_dbg(hdev, "firmware version: %c.%c\n",
tdev->version.major, tdev->version.minor); tdev->version.major, tdev->version.minor);
...@@ -237,17 +233,18 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -237,17 +233,18 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (!tdev->fwinfo) { if (!tdev->fwinfo) {
hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); hid_err(hdev, "unsupported firmware %c\n", tdev->version.major);
err = -ENODEV; return -ENODEV;
goto stop;
} }
tdev->rgb = devm_kzalloc(&hdev->dev, tdev->rgb = devm_kzalloc(&hdev->dev,
sizeof(struct thingm_rgb) * tdev->fwinfo->numrgb, sizeof(struct thingm_rgb) * tdev->fwinfo->numrgb,
GFP_KERNEL); GFP_KERNEL);
if (!tdev->rgb) { if (!tdev->rgb)
err = -ENOMEM; return -ENOMEM;
goto stop;
} err = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
if (err)
return err;
for (i = 0; i < tdev->fwinfo->numrgb; ++i) { for (i = 0; i < tdev->fwinfo->numrgb; ++i) {
struct thingm_rgb *rgb = tdev->rgb + i; struct thingm_rgb *rgb = tdev->rgb + i;
...@@ -255,15 +252,13 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -255,15 +252,13 @@ static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
rgb->tdev = tdev; rgb->tdev = tdev;
rgb->num = tdev->fwinfo->first + i; rgb->num = tdev->fwinfo->first + i;
err = thingm_init_rgb(rgb); err = thingm_init_rgb(rgb);
if (err) if (err) {
goto stop; hid_hw_stop(hdev);
return err;
}
} }
return 0; return 0;
stop:
hid_hw_stop(hdev);
error:
return err;
} }
static const struct hid_device_id thingm_table[] = { static const struct hid_device_id thingm_table[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment