提交 33c6ad98 编写于 作者: A Alan Stern 提交者: Zheng Zengkai

USB: gadget: Fix double-free bug in raw_gadget driver

stable inclusion
from stable-v5.10.127
commit 656eca37aae1f7dad26693ab1bd1c1d4f110741c
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5XDDK

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=656eca37aae1f7dad26693ab1bd1c1d4f110741c

--------------------------------

commit 90bc2af2 upstream.

Re-reading a recently merged fix to the raw_gadget driver showed that
it inadvertently introduced a double-free bug in a failure pathway.
If raw_ioctl_init() encounters an error after the driver ID number has
been allocated, it deallocates the ID number before returning.  But
when dev_free() runs later on, it will then try to deallocate the ID
number a second time.

Closely related to this issue is another error in the recent fix: The
ID number is stored in the raw_dev structure before the code checks to
see whether the structure has already been initialized, in which case
the new ID number would overwrite the earlier value.

The solution to both bugs is to keep the new ID number in a local
variable, and store it in the raw_dev structure only after the check
for prior initialization.  No errors can occur after that point, so
the double-free will never happen.

Fixes: f2d8c260 ("usb: gadget: Fix non-unique driver names in raw-gadget driver")
CC: Andrey Konovalov <andreyknvl@gmail.com>
CC: <stable@vger.kernel.org>
Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YrMrRw5AyIZghN0v@rowland.harvard.eduSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
上级 ddb2716d
......@@ -429,6 +429,7 @@ static int raw_release(struct inode *inode, struct file *fd)
static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
{
int ret = 0;
int driver_id_number;
struct usb_raw_init arg;
char *udc_driver_name;
char *udc_device_name;
......@@ -451,10 +452,9 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
return -EINVAL;
}
ret = ida_alloc(&driver_id_numbers, GFP_KERNEL);
if (ret < 0)
return ret;
dev->driver_id_number = ret;
driver_id_number = ida_alloc(&driver_id_numbers, GFP_KERNEL);
if (driver_id_number < 0)
return driver_id_number;
driver_driver_name = kmalloc(DRIVER_DRIVER_NAME_LENGTH_MAX, GFP_KERNEL);
if (!driver_driver_name) {
......@@ -462,7 +462,7 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
goto out_free_driver_id_number;
}
snprintf(driver_driver_name, DRIVER_DRIVER_NAME_LENGTH_MAX,
DRIVER_NAME ".%d", dev->driver_id_number);
DRIVER_NAME ".%d", driver_id_number);
udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);
if (!udc_driver_name) {
......@@ -506,6 +506,7 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
dev->driver.driver.name = driver_driver_name;
dev->driver.udc_name = udc_device_name;
dev->driver.match_existing_only = 1;
dev->driver_id_number = driver_id_number;
dev->state = STATE_DEV_INITIALIZED;
spin_unlock_irqrestore(&dev->lock, flags);
......@@ -520,7 +521,7 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
out_free_driver_driver_name:
kfree(driver_driver_name);
out_free_driver_id_number:
ida_free(&driver_id_numbers, dev->driver_id_number);
ida_free(&driver_id_numbers, driver_id_number);
return ret;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册