From: Hans de Goede Date: Sat, 20 Apr 2019 11:21:50 +0000 (+0200) Subject: HID: logitech-dj: protect the paired_dj_devices access in add_djhid_dev with the... X-Git-Tag: v5.4-rc1~1093^2^4~29 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f41d766c34cbab024412d433a43d2d83a37e5135;p=platform%2Fkernel%2Flinux-rpi.git HID: logitech-dj: protect the paired_dj_devices access in add_djhid_dev with the lock This protects against logi_dj_recv_add_djhid_device, adding a device to paired_dj_devices from the delayedwork callback, racing versus logi_dj_raw_event trying to access that device. Signed-off-by: Hans de Goede Signed-off-by: Benjamin Tissoires --- diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9e5aac7..e9a1657 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -393,12 +393,14 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, struct hid_device *dj_hiddev; struct dj_device *dj_dev; u8 device_index = workitem->device_index; + unsigned long flags; /* Device index goes from 1 to 6, we need 3 bytes to store the * semicolon, the index, and a null terminator */ unsigned char tmpstr[3]; + /* We are the only one ever adding a device, no need to lock */ if (djrcv_dev->paired_dj_devices[device_index]) { /* The device is already known. No need to reallocate it. */ dbg_hid("%s: device is already known\n", __func__); @@ -443,7 +445,9 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, dj_dev->device_index = device_index; dj_hiddev->driver_data = dj_dev; + spin_lock_irqsave(&djrcv_dev->lock, flags); djrcv_dev->paired_dj_devices[device_index] = dj_dev; + spin_unlock_irqrestore(&djrcv_dev->lock, flags); if (hid_add_device(dj_hiddev)) { dev_err(&djrcv_hdev->dev, "%s: failed adding dj_device\n", @@ -454,7 +458,9 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, return; hid_add_device_fail: + spin_lock_irqsave(&djrcv_dev->lock, flags); djrcv_dev->paired_dj_devices[device_index] = NULL; + spin_unlock_irqrestore(&djrcv_dev->lock, flags); kfree(dj_dev); dj_device_allocate_fail: hid_destroy_device(dj_hiddev);