tty: don't leak cdev in tty_cdev_add()
Commita3a10ce342
("Avoid usb reset crashes by making tty_io cdevs truly dynamic") which mixes using cdev_alloc() and cdev_init() is problematic. Subsequent call to cdev_init() after cdev_alloc() sets kobj release method from cdev_dynamic_release() to cdev_default_release() and thus makes it impossible to free allocated cdev. This patch also consolidates error path of cdev_add() as cdev can also leak here if things went wrong. Signed-off-by: Leon Yu <chianglungyu@gmail.com> Fixes:a3a10ce342
("Avoid usb reset crashes by making tty_io cdevs truly dynamic") Acked-by: Richard Watts <rrw@kynesim.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0c727a4204
commit
c1a752ba2d
1 changed files with 7 additions and 2 deletions
|
@ -3151,13 +3151,18 @@ struct class *tty_class;
|
||||||
static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
|
static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
|
||||||
unsigned int index, unsigned int count)
|
unsigned int index, unsigned int count)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
/* init here, since reused cdevs cause crashes */
|
/* init here, since reused cdevs cause crashes */
|
||||||
driver->cdevs[index] = cdev_alloc();
|
driver->cdevs[index] = cdev_alloc();
|
||||||
if (!driver->cdevs[index])
|
if (!driver->cdevs[index])
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
cdev_init(driver->cdevs[index], &tty_fops);
|
driver->cdevs[index]->ops = &tty_fops;
|
||||||
driver->cdevs[index]->owner = driver->owner;
|
driver->cdevs[index]->owner = driver->owner;
|
||||||
return cdev_add(driver->cdevs[index], dev, count);
|
err = cdev_add(driver->cdevs[index], dev, count);
|
||||||
|
if (err)
|
||||||
|
kobject_put(&driver->cdevs[index]->kobj);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue