diff options
author | Jiri Slaby <jslaby@suse.cz> | 2021-07-23 09:43:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-07-27 12:17:20 +0200 |
commit | 0524513afe45a4a79f418c0377160b7712cab78a (patch) | |
tree | eab43a3f41c183818029805709a1abbf6625ef21 /drivers/tty/hvc | |
parent | 7ccbdcc4d08a6d7041e4849219bbb12ffa45db4c (diff) | |
download | linux-0524513afe45a4a79f418c0377160b7712cab78a.tar.gz |
tty: don't store semi-state into tty drivers
When a tty driver pointer is used as a return value of struct
console's device() hook, don't store a semi-state into global variable
which holds the tty driver. It could mean console::device() would return
a bogus value. This is important esp. after the next patch where we
switch from alloc_tty_driver to tty_alloc_driver. tty_alloc_driver
returns ERR_PTR in case of error and that might have unexpected results
as the code doesn't expect this.
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Cc: Felipe Balbi <balbi@kernel.org>
Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
Acked-by: Helge Deller <deller@gmx.de> # parisc
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20210723074317.32690-4-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r-- | drivers/tty/hvc/hvsi.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index f0bc8e780051..bfde7b1936a5 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1038,29 +1038,30 @@ static const struct tty_operations hvsi_ops = { static int __init hvsi_init(void) { + struct tty_driver *driver; int i, ret; - hvsi_driver = alloc_tty_driver(hvsi_count); - if (!hvsi_driver) + driver = alloc_tty_driver(hvsi_count); + if (!driver) return -ENOMEM; - hvsi_driver->driver_name = "hvsi"; - hvsi_driver->name = "hvsi"; - hvsi_driver->major = HVSI_MAJOR; - hvsi_driver->minor_start = HVSI_MINOR; - hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; - hvsi_driver->init_termios = tty_std_termios; - hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; - hvsi_driver->init_termios.c_ispeed = 9600; - hvsi_driver->init_termios.c_ospeed = 9600; - hvsi_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(hvsi_driver, &hvsi_ops); + driver->driver_name = "hvsi"; + driver->name = "hvsi"; + driver->major = HVSI_MAJOR; + driver->minor_start = HVSI_MINOR; + driver->type = TTY_DRIVER_TYPE_SYSTEM; + driver->init_termios = tty_std_termios; + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; + driver->init_termios.c_ispeed = 9600; + driver->init_termios.c_ospeed = 9600; + driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(driver, &hvsi_ops); for (i=0; i < hvsi_count; i++) { struct hvsi_struct *hp = &hvsi_ports[i]; int ret = 1; - tty_port_link_device(&hp->port, hvsi_driver, i); + tty_port_link_device(&hp->port, driver, i); ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); if (ret) @@ -1069,12 +1070,14 @@ static int __init hvsi_init(void) } hvsi_wait = wait_for_state; /* irqs active now */ - ret = tty_register_driver(hvsi_driver); + ret = tty_register_driver(driver); if (ret) { pr_err("Couldn't register hvsi console driver\n"); goto err_free_irq; } + hvsi_driver = driver; + printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); return 0; @@ -1085,7 +1088,7 @@ err_free_irq: free_irq(hp->virq, hp); } - tty_driver_kref_put(hvsi_driver); + tty_driver_kref_put(driver); return ret; } |