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: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
43a4a04d4d
commit
1d1b564ff8
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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[] = {
|
||||||
|
|
Loading…
Reference in a new issue