mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
usb: gadget: f_hid: don't call cdev_init while cdev in use
When calling unbind, then bind again, cdev_init reinitialized the cdev, even though there may still be references to it. That's the case when the /dev/hidg* device is still opened. This obviously unsafe behavior like oopes. This fixes this by using cdev_alloc to put the cdev on the heap. That way, we can simply allocate a new one in hidg_bind. Closes: https://lore.kernel.org/linux-usb/CAN9vWDKZn0Ts5JyV2_xcAmbnBEi0znMLg_USMFrShRryXrgWGQ@mail.gmail.com/T/#m2cb0dba3633b67b2a679c98499508267d1508881 Cc: stable <stable@kernel.org> Signed-off-by: Michael Zimmermann <sigmaepsilon92@gmail.com> Link: https://patch.msgid.link/20260327192209.59945-1-sigmaepsilon92@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0c8935642c
commit
81ebd43cc0
|
|
@ -106,7 +106,7 @@ struct f_hidg {
|
|||
struct list_head report_list;
|
||||
|
||||
struct device dev;
|
||||
struct cdev cdev;
|
||||
struct cdev *cdev;
|
||||
struct usb_function func;
|
||||
|
||||
struct usb_ep *in_ep;
|
||||
|
|
@ -749,8 +749,9 @@ static int f_hidg_release(struct inode *inode, struct file *fd)
|
|||
|
||||
static int f_hidg_open(struct inode *inode, struct file *fd)
|
||||
{
|
||||
struct kobject *parent = inode->i_cdev->kobj.parent;
|
||||
struct f_hidg *hidg =
|
||||
container_of(inode->i_cdev, struct f_hidg, cdev);
|
||||
container_of(parent, struct f_hidg, dev.kobj);
|
||||
|
||||
fd->private_data = hidg;
|
||||
|
||||
|
|
@ -1285,8 +1286,12 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
}
|
||||
|
||||
/* create char device */
|
||||
cdev_init(&hidg->cdev, &f_hidg_fops);
|
||||
status = cdev_device_add(&hidg->cdev, &hidg->dev);
|
||||
hidg->cdev = cdev_alloc();
|
||||
if (!hidg->cdev)
|
||||
goto fail_free_all;
|
||||
hidg->cdev->ops = &f_hidg_fops;
|
||||
|
||||
status = cdev_device_add(hidg->cdev, &hidg->dev);
|
||||
if (status)
|
||||
goto fail_free_all;
|
||||
|
||||
|
|
@ -1588,7 +1593,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||
{
|
||||
struct f_hidg *hidg = func_to_hidg(f);
|
||||
|
||||
cdev_device_del(&hidg->cdev, &hidg->dev);
|
||||
cdev_device_del(hidg->cdev, &hidg->dev);
|
||||
destroy_workqueue(hidg->workqueue);
|
||||
usb_free_all_descriptors(f);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user