Skip to content

Commit

Permalink
tty: don't leak cdev in tty_cdev_add()
Browse files Browse the repository at this point in the history
Commit a3a10ce ("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: a3a10ce ("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>
  • Loading branch information
clyu authored and gregkh committed Oct 4, 2015
1 parent 0c727a4 commit c1a752b
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3151,13 +3151,18 @@ struct class *tty_class;
static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
unsigned int index, unsigned int count)
{
int err;

/* init here, since reused cdevs cause crashes */
driver->cdevs[index] = cdev_alloc();
if (!driver->cdevs[index])
return -ENOMEM;
cdev_init(driver->cdevs[index], &tty_fops);
driver->cdevs[index]->ops = &tty_fops;
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;
}

/**
Expand Down

0 comments on commit c1a752b

Please sign in to comment.