HID: wacom: Prevent potential null dereference after disconnect
Subsystems (2)
PATCH 1/1 HID: wacom: Prevent potential null dereference after disconnect
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g. wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.
--- drivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/hid/wacom_sys.c +12 -1
@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err; +if (!wacom) +return -ENODEV ; + err =kstrtouint (buf,10 , &id);if (err)return err;
@@ -666,6 +669,8 @@ static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\struct wacom *wacom =hid_get_drvdata (hdev); \ +if (!wacom) \ +return -ENODEV ; \return scnprintf (buf,PAGE_SIZE ,"%d\n" , \ wacom->led.select[SET_ID ]); \ } \
@@ -702,7 +707,8 @@ static ssize_t wacom_##name##_luminance_store(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\struct wacom *wacom =hid_get_drvdata (hdev); \ - \ +if (!wacom) \ +return -ENODEV ; \return wacom_luminance_store (wacom, &wacom->led.field, \ buf, count); \ } \
@@ -710,6 +716,8 @@ static ssize_t wacom_##name##_luminance_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct wacom *wacom = dev_get_drvdata(dev); \ +if (!wacom) \ +return -ENODEV ;return scnprintf (buf,PAGE_SIZE ,"%d\n" , wacom->led.field); \ } \ static DEVICE_ATTR(name##_luminance, DEV_ATTR_RW_PERM, \
@@ -729,6 +737,9 @@ static ssize_t wacom_button_image_store(struct device *dev, int button_id,unsigned len;u8 xfer_id; +if (!wacom) +return -ENODEV ; +if (hdev->bus ==BUS_BLUETOOTH ) { len =256 ; xfer_id =WAC_CMD_ICON_BT_XFER ;
Signature · 1 line
2.1.2
PATCH v2 1/1 HID: wacom: Prevent potential null dereference after disconnect
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g. wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.
---
Changes in v2:
* Added in missing escape character
drivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/hid/wacom_sys.c +12 -1
@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err; +if (!wacom) +return -ENODEV ; + err =kstrtouint (buf,10 , &id);if (err)return err;
@@ -666,6 +669,8 @@ static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\struct wacom *wacom =hid_get_drvdata (hdev); \ +if (!wacom) \ +return -ENODEV ; \return scnprintf (buf,PAGE_SIZE ,"%d\n" , \ wacom->led.select[SET_ID ]); \ } \
@@ -702,7 +707,8 @@ static ssize_t wacom_##name##_luminance_store(struct device *dev, \ { \ struct hid_device *hdev = container_of(dev, struct hid_device, dev);\struct wacom *wacom =hid_get_drvdata (hdev); \ - \ +if (!wacom) \ +return -ENODEV ; \return wacom_luminance_store (wacom, &wacom->led.field, \ buf, count); \ } \
@@ -710,6 +716,8 @@ static ssize_t wacom_##name##_luminance_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct wacom *wacom = dev_get_drvdata(dev); \ +if (!wacom) \ +return -ENODEV ; \return scnprintf (buf,PAGE_SIZE ,"%d\n" , wacom->led.field); \ } \ static DEVICE_ATTR(name##_luminance, DEV_ATTR_RW_PERM, \
@@ -729,6 +737,9 @@ static ssize_t wacom_button_image_store(struct device *dev, int button_id,unsigned len;u8 xfer_id; +if (!wacom) +return -ENODEV ; +if (hdev->bus ==BUS_BLUETOOTH ) { len =256 ; xfer_id =WAC_CMD_ICON_BT_XFER ;
Signature · 1 line
2.1.2
Quoted 18 lines · Jason Gerecke
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g.
wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.Signed-off-by Jason Gerecke <[email protected]>---
Changes in v2:
* Added in missing escape characterdrivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)drivers/hid/wacom_sys.c +0
-0
drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 646
Quoted 6 lines
drivers/hid/wacom_sys.c +3
-0@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err; +if (!wacom) +return -ENODEV ; +
Strong NAK. If device could disappear before this check it could as well disappear after your check.
This patch does not solve anything.
drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 649
Quoted 3 lines
drivers/hid/wacom_sys.c +0
-0err =kstrtouint (buf,10 , &id);if (err)return err;
Thanks.
Signature · 1 line
Dmitry
Quoted 22 lines · Dmitry Torokhov
Quoted 21 lines · Jason Gerecke
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g.
wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.Signed-off-by Jason Gerecke <[email protected]>---
Changes in v2:
* Added in missing escape characterdrivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)drivers/hid/wacom_sys.c +0
-0@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err;
Quoted 9 lines
drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 646
Quoted 3 lines
drivers/hid/wacom_sys.c +3
-0+if (!wacom) +return -ENODEV ; +Strong NAK. If device could disappear before this check it could as well disappear after your check.
This patch does not solve anything.
I assume I'll want to either disable interrupts or take a lock depending on if wacom_remove is called from within the interrupt context, but I haven't had to deal with concurrency in the kernel before so I'm not entirely sure which option (or which primitive if locking) would be appropriate...
Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one /
(That is to say, eight) to the two, /
But you can’t take seven from three, /
So you look at the sixty-fours....
Quoted 4 lines
drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 649
Quoted 3 lines
drivers/hid/wacom_sys.c +0
-0err =kstrtouint (buf,10 , &id);if (err)return err;
Quoted 8 lines
Thanks.
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 31 lines · Jason Gerecke
Quoted 29 lines · Dmitry Torokhov
Quoted 18 lines · Jason Gerecke
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g.
wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.Signed-off-by Jason Gerecke <[email protected]>---
Changes in v2:
* Added in missing escape characterdrivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)drivers/hid/wacom_sys.c +0
-0drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 646
Quoted 6 lines
drivers/hid/wacom_sys.c +3
-0@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err; +if (!wacom) +return -ENODEV ; +Strong NAK. If device could disappear before this check it could as well disappear after your check.
Quoted 8 lines
Quoted 2 lines
This patch does not solve anything.
I assume I'll want to either disable interrupts or take a lock depending on if
wacom_removeis called from within the interrupt context, but I haven't had to deal with concurrency in the kernel before so I'm not entirely sure which option (or which primitive if locking) would be appropriate...
Actually the sysfs core should not allow anyone descend into sysfs show/store methods once you return from sysfs_remove*(). So you need to make sure that pointer is valid until then.
Thanks.
Signature · 1 line
Dmitry
Quoted 41 lines · Dmitry Torokhov
Quoted 31 lines · Jason Gerecke
Quoted 29 lines · Dmitry Torokhov
Quoted 18 lines · Jason Gerecke
Repeated connect/disconnect cycles under GNOME can trigger an occasional OOPS from within e.g.
wacom_led_select_store, presumably due to a timing issue where userspace begins setting a value immediately before the device disconnects and our shared data is whisked away.Signed-off-by Jason Gerecke <[email protected]>---
Changes in v2:
* Added in missing escape characterdrivers/hid/wacom_sys.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)drivers/hid/wacom_sys.c +0
-0drivers/hid/wacom_sys.c static ssize_t wacom_led_select_store(struct device *dev, int set_id, · line 646
Quoted 6 lines
drivers/hid/wacom_sys.c +3
-0@@ -641,6 +641,9 @@ static ssize_t wacom_led_select_store(struct device *dev, int set_id,unsigned int id;int err; +if (!wacom) +return -ENODEV ; +Strong NAK. If device could disappear before this check it could as well disappear after your check.
Quoted 8 lines
Quoted 2 lines
This patch does not solve anything.
I assume I'll want to either disable interrupts or take a lock depending on if
wacom_removeis called from within the interrupt context, but I haven't had to deal with concurrency in the kernel before so I'm not entirely sure which option (or which primitive if locking) would be appropriate...
Quoted 8 lines
Actually the sysfs core should not allow anyone descend into sysfs show/store methods once you return from sysfs_remove*(). So you need to make sure that pointer is valid until then.
Thanks.
--
Dmitry
Hmm. That's odd. The wacom_remove function calls wacom_destroy_leds (which is responsible for removing those sysfs nodes) prior to calling wacom_remove_shared_data (which is responsible for freeing that pointer). I could imagine that a disconnect which occurred after the sysfs checks were satisfied but before our function was called would be able to get around that, but I don't know if the kernel can be interrupted while the sysfs write is being handled. I'll double-check what the actual state of things is when the OOPS happens...
Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one /
(That is to say, eight) to the two, /
But you can’t take seven from three, /
So you look at the sixty-fours....
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html