mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
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>
This commit is contained in:
parent
7ccbdcc4d0
commit
0524513afe
@ -120,35 +120,38 @@ early_param("debug", nf_debug_setup);
|
||||
|
||||
static int __init nfcon_init(void)
|
||||
{
|
||||
struct tty_driver *driver;
|
||||
int res;
|
||||
|
||||
stderr_id = nf_get_id("NF_STDERR");
|
||||
if (!stderr_id)
|
||||
return -ENODEV;
|
||||
|
||||
nfcon_tty_driver = alloc_tty_driver(1);
|
||||
if (!nfcon_tty_driver)
|
||||
driver = alloc_tty_driver(1);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
tty_port_init(&nfcon_tty_port);
|
||||
|
||||
nfcon_tty_driver->driver_name = "nfcon";
|
||||
nfcon_tty_driver->name = "nfcon";
|
||||
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||
nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
|
||||
nfcon_tty_driver->init_termios = tty_std_termios;
|
||||
nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
driver->driver_name = "nfcon";
|
||||
driver->name = "nfcon";
|
||||
driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||
driver->subtype = SYSTEM_TYPE_TTY;
|
||||
driver->init_termios = tty_std_termios;
|
||||
driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
|
||||
tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
|
||||
tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0);
|
||||
res = tty_register_driver(nfcon_tty_driver);
|
||||
tty_set_operations(driver, &nfcon_tty_ops);
|
||||
tty_port_link_device(&nfcon_tty_port, driver, 0);
|
||||
res = tty_register_driver(driver);
|
||||
if (res) {
|
||||
pr_err("failed to register nfcon tty driver\n");
|
||||
put_tty_driver(nfcon_tty_driver);
|
||||
put_tty_driver(driver);
|
||||
tty_port_destroy(&nfcon_tty_port);
|
||||
return res;
|
||||
}
|
||||
|
||||
nfcon_tty_driver = driver;
|
||||
|
||||
if (!(nf_console.flags & CON_ENABLED))
|
||||
register_console(&nf_console);
|
||||
|
||||
|
@ -138,6 +138,7 @@ static struct tty_driver *pdc_console_tty_driver;
|
||||
|
||||
static int __init pdc_console_tty_driver_init(void)
|
||||
{
|
||||
struct tty_driver *driver;
|
||||
int err;
|
||||
|
||||
/* Check if the console driver is still registered.
|
||||
@ -160,31 +161,32 @@ static int __init pdc_console_tty_driver_init(void)
|
||||
printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
|
||||
pdc_cons.flags &= ~CON_BOOT;
|
||||
|
||||
pdc_console_tty_driver = alloc_tty_driver(1);
|
||||
|
||||
if (!pdc_console_tty_driver)
|
||||
driver = alloc_tty_driver(1);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
tty_port_init(&tty_port);
|
||||
|
||||
pdc_console_tty_driver->driver_name = "pdc_cons";
|
||||
pdc_console_tty_driver->name = "ttyB";
|
||||
pdc_console_tty_driver->major = MUX_MAJOR;
|
||||
pdc_console_tty_driver->minor_start = 0;
|
||||
pdc_console_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||
pdc_console_tty_driver->init_termios = tty_std_termios;
|
||||
pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW |
|
||||
driver->driver_name = "pdc_cons";
|
||||
driver->name = "ttyB";
|
||||
driver->major = MUX_MAJOR;
|
||||
driver->minor_start = 0;
|
||||
driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||
driver->init_termios = tty_std_termios;
|
||||
driver->flags = TTY_DRIVER_REAL_RAW |
|
||||
TTY_DRIVER_RESET_TERMIOS;
|
||||
tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops);
|
||||
tty_port_link_device(&tty_port, pdc_console_tty_driver, 0);
|
||||
tty_set_operations(driver, &pdc_console_tty_ops);
|
||||
tty_port_link_device(&tty_port, driver, 0);
|
||||
|
||||
err = tty_register_driver(pdc_console_tty_driver);
|
||||
err = tty_register_driver(driver);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
|
||||
tty_port_destroy(&tty_port);
|
||||
return err;
|
||||
}
|
||||
|
||||
pdc_console_tty_driver = driver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(pdc_console_tty_driver_init);
|
||||
|
@ -136,39 +136,42 @@ static const struct tty_operations serial_ops = {
|
||||
|
||||
static int __init rs_init(void)
|
||||
{
|
||||
struct tty_driver *driver;
|
||||
int ret;
|
||||
|
||||
serial_driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES);
|
||||
if (!serial_driver)
|
||||
driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
tty_port_init(&serial_port);
|
||||
|
||||
/* Initialize the tty_driver structure */
|
||||
|
||||
serial_driver->driver_name = "iss_serial";
|
||||
serial_driver->name = "ttyS";
|
||||
serial_driver->major = TTY_MAJOR;
|
||||
serial_driver->minor_start = 64;
|
||||
serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
serial_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
serial_driver->init_termios = tty_std_termios;
|
||||
serial_driver->init_termios.c_cflag =
|
||||
driver->driver_name = "iss_serial";
|
||||
driver->name = "ttyS";
|
||||
driver->major = TTY_MAJOR;
|
||||
driver->minor_start = 64;
|
||||
driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
driver->init_termios = tty_std_termios;
|
||||
driver->init_termios.c_cflag =
|
||||
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
serial_driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
|
||||
tty_set_operations(serial_driver, &serial_ops);
|
||||
tty_port_link_device(&serial_port, serial_driver, 0);
|
||||
tty_set_operations(driver, &serial_ops);
|
||||
tty_port_link_device(&serial_port, driver, 0);
|
||||
|
||||
ret = tty_register_driver(serial_driver);
|
||||
ret = tty_register_driver(driver);
|
||||
if (ret) {
|
||||
pr_err("Couldn't register serial driver\n");
|
||||
tty_driver_kref_put(serial_driver);
|
||||
tty_driver_kref_put(driver);
|
||||
tty_port_destroy(&serial_port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
serial_driver = driver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1490,34 +1490,35 @@ static const struct tty_port_operations amiga_port_ops = {
|
||||
static int __init amiga_serial_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct serial_state *state = &serial_state;
|
||||
struct tty_driver *driver;
|
||||
unsigned long flags;
|
||||
int error;
|
||||
|
||||
serial_driver = alloc_tty_driver(1);
|
||||
if (!serial_driver)
|
||||
driver = alloc_tty_driver(1);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Initialize the tty_driver structure */
|
||||
|
||||
serial_driver->driver_name = "amiserial";
|
||||
serial_driver->name = "ttyS";
|
||||
serial_driver->major = TTY_MAJOR;
|
||||
serial_driver->minor_start = 64;
|
||||
serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
serial_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
serial_driver->init_termios = tty_std_termios;
|
||||
serial_driver->init_termios.c_cflag =
|
||||
driver->driver_name = "amiserial";
|
||||
driver->name = "ttyS";
|
||||
driver->major = TTY_MAJOR;
|
||||
driver->minor_start = 64;
|
||||
driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
driver->init_termios = tty_std_termios;
|
||||
driver->init_termios.c_cflag =
|
||||
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
serial_driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
tty_set_operations(serial_driver, &serial_ops);
|
||||
driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
tty_set_operations(driver, &serial_ops);
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->port = (int)&amiga_custom.serdatr; /* Just to give it a value */
|
||||
tty_port_init(&state->tport);
|
||||
state->tport.ops = &amiga_port_ops;
|
||||
tty_port_link_device(&state->tport, serial_driver, 0);
|
||||
tty_port_link_device(&state->tport, driver, 0);
|
||||
|
||||
error = tty_register_driver(serial_driver);
|
||||
error = tty_register_driver(driver);
|
||||
if (error)
|
||||
goto fail_put_tty_driver;
|
||||
|
||||
@ -1558,15 +1559,17 @@ static int __init amiga_serial_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, state);
|
||||
|
||||
serial_driver = driver;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_irq:
|
||||
free_irq(IRQ_AMIGA_TBE, state);
|
||||
fail_unregister:
|
||||
tty_unregister_driver(serial_driver);
|
||||
tty_unregister_driver(driver);
|
||||
fail_put_tty_driver:
|
||||
tty_port_destroy(&state->tport);
|
||||
put_tty_driver(serial_driver);
|
||||
put_tty_driver(driver);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -751,6 +751,7 @@ static struct platform_driver ehv_bc_tty_driver = {
|
||||
*/
|
||||
static int __init ehv_bc_init(void)
|
||||
{
|
||||
struct tty_driver *driver;
|
||||
struct device_node *np;
|
||||
unsigned int count = 0; /* Number of elements in bcs[] */
|
||||
int ret;
|
||||
@ -773,26 +774,28 @@ static int __init ehv_bc_init(void)
|
||||
if (!bcs)
|
||||
return -ENOMEM;
|
||||
|
||||
ehv_bc_driver = alloc_tty_driver(count);
|
||||
if (!ehv_bc_driver) {
|
||||
driver = alloc_tty_driver(count);
|
||||
if (!driver) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_bcs;
|
||||
}
|
||||
|
||||
ehv_bc_driver->driver_name = "ehv-bc";
|
||||
ehv_bc_driver->name = ehv_bc_console.name;
|
||||
ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE;
|
||||
ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE;
|
||||
ehv_bc_driver->init_termios = tty_std_termios;
|
||||
ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||
tty_set_operations(ehv_bc_driver, &ehv_bc_ops);
|
||||
driver->driver_name = "ehv-bc";
|
||||
driver->name = ehv_bc_console.name;
|
||||
driver->type = TTY_DRIVER_TYPE_CONSOLE;
|
||||
driver->subtype = SYSTEM_TYPE_CONSOLE;
|
||||
driver->init_termios = tty_std_termios;
|
||||
driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||
tty_set_operations(driver, &ehv_bc_ops);
|
||||
|
||||
ret = tty_register_driver(ehv_bc_driver);
|
||||
ret = tty_register_driver(driver);
|
||||
if (ret) {
|
||||
pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
|
||||
goto err_put_tty_driver;
|
||||
}
|
||||
|
||||
ehv_bc_driver = driver;
|
||||
|
||||
ret = platform_driver_register(&ehv_bc_tty_driver);
|
||||
if (ret) {
|
||||
pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
|
||||
@ -803,9 +806,10 @@ static int __init ehv_bc_init(void)
|
||||
return 0;
|
||||
|
||||
err_deregister_tty_driver:
|
||||
tty_unregister_driver(ehv_bc_driver);
|
||||
ehv_bc_driver = NULL;
|
||||
tty_unregister_driver(driver);
|
||||
err_put_tty_driver:
|
||||
put_tty_driver(ehv_bc_driver);
|
||||
put_tty_driver(driver);
|
||||
err_free_bcs:
|
||||
kfree(bcs);
|
||||
|
||||
|
@ -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 @@ static int __init hvsi_init(void)
|
||||
|
||||
free_irq(hp->virq, hp);
|
||||
}
|
||||
tty_driver_kref_put(hvsi_driver);
|
||||
tty_driver_kref_put(driver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1445,51 +1445,53 @@ EXPORT_SYMBOL_GPL(gserial_resume);
|
||||
|
||||
static int userial_init(void)
|
||||
{
|
||||
struct tty_driver *driver;
|
||||
unsigned i;
|
||||
int status;
|
||||
|
||||
gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS);
|
||||
if (!gs_tty_driver)
|
||||
driver = alloc_tty_driver(MAX_U_SERIAL_PORTS);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
gs_tty_driver->driver_name = "g_serial";
|
||||
gs_tty_driver->name = "ttyGS";
|
||||
driver->driver_name = "g_serial";
|
||||
driver->name = "ttyGS";
|
||||
/* uses dynamically assigned dev_t values */
|
||||
|
||||
gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||
gs_tty_driver->init_termios = tty_std_termios;
|
||||
driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||
driver->init_termios = tty_std_termios;
|
||||
|
||||
/* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
|
||||
* MS-Windows. Otherwise, most of these flags shouldn't affect
|
||||
* anything unless we were to actually hook up to a serial line.
|
||||
*/
|
||||
gs_tty_driver->init_termios.c_cflag =
|
||||
driver->init_termios.c_cflag =
|
||||
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
gs_tty_driver->init_termios.c_ispeed = 9600;
|
||||
gs_tty_driver->init_termios.c_ospeed = 9600;
|
||||
driver->init_termios.c_ispeed = 9600;
|
||||
driver->init_termios.c_ospeed = 9600;
|
||||
|
||||
tty_set_operations(gs_tty_driver, &gs_tty_ops);
|
||||
tty_set_operations(driver, &gs_tty_ops);
|
||||
for (i = 0; i < MAX_U_SERIAL_PORTS; i++)
|
||||
mutex_init(&ports[i].lock);
|
||||
|
||||
/* export the driver ... */
|
||||
status = tty_register_driver(gs_tty_driver);
|
||||
status = tty_register_driver(driver);
|
||||
if (status) {
|
||||
pr_err("%s: cannot register, err %d\n",
|
||||
__func__, status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gs_tty_driver = driver;
|
||||
|
||||
pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
|
||||
MAX_U_SERIAL_PORTS,
|
||||
(MAX_U_SERIAL_PORTS == 1) ? "" : "s");
|
||||
|
||||
return status;
|
||||
fail:
|
||||
put_tty_driver(gs_tty_driver);
|
||||
gs_tty_driver = NULL;
|
||||
put_tty_driver(driver);
|
||||
return status;
|
||||
}
|
||||
module_init(userial_init);
|
||||
|
Loading…
Reference in New Issue
Block a user