tty_io: check return code of tty_register_device
authorVasiliy Kulikov <segooon@gmail.com>
Sun, 5 Sep 2010 18:32:22 +0000 (22:32 +0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:20:03 +0000 (10:20 -0700)
Function tty_register_device may return ERR_PTR(...). Check for it.

Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/char/tty_io.c

index d6c659f2f659f43cf1202d8da5fa3bd2d415542d..e185db36f8ad1e33830f8521f1731f65d6a8c80c 100644 (file)
@@ -3004,6 +3004,7 @@ int tty_register_driver(struct tty_driver *driver)
        int i;
        dev_t dev;
        void **p = NULL;
+       struct device *d;
 
        if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
                p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
@@ -3051,12 +3052,31 @@ int tty_register_driver(struct tty_driver *driver)
        mutex_unlock(&tty_mutex);
 
        if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
-               for (i = 0; i < driver->num; i++)
-                   tty_register_device(driver, i, NULL);
+               for (i = 0; i < driver->num; i++) {
+                       d = tty_register_device(driver, i, NULL);
+                       if (IS_ERR(d)) {
+                               error = PTR_ERR(d);
+                               goto err;
+                       }
+               }
        }
        proc_tty_register_driver(driver);
        driver->flags |= TTY_DRIVER_INSTALLED;
        return 0;
+
+err:
+       for (i--; i >= 0; i--)
+               tty_unregister_device(driver, i);
+
+       mutex_lock(&tty_mutex);
+       list_del(&driver->tty_drivers);
+       mutex_unlock(&tty_mutex);
+
+       unregister_chrdev_region(dev, driver->num);
+       driver->ttys = NULL;
+       driver->termios = NULL;
+       kfree(p);
+       return error;
 }
 
 EXPORT_SYMBOL(tty_register_driver);