| From a89936cce87d60766a75732a9e7e25c51164f47c Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Fri, 17 Sep 2021 13:46:17 +0200 |
| Subject: ipack: ipoctal: fix stack information leak |
| |
| From: Johan Hovold <johan@kernel.org> |
| |
| commit a89936cce87d60766a75732a9e7e25c51164f47c upstream. |
| |
| The tty driver name is used also after registering the driver and must |
| specifically not be allocated on the stack to avoid leaking information |
| to user space (or triggering an oops). |
| |
| Drivers should not try to encode topology information in the tty device |
| name but this one snuck in through staging without anyone noticing and |
| another driver has since copied this malpractice. |
| |
| Fixing the ABI is a separate issue, but this at least plugs the security |
| hole. |
| |
| Fixes: ba4dc61fe8c5 ("Staging: ipack: add support for IP-OCTAL mezzanine board") |
| Cc: stable@vger.kernel.org # 3.5 |
| Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Link: https://lore.kernel.org/r/20210917114622.5412-2-johan@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/ipack/devices/ipoctal.c | 19 ++++++++++++++----- |
| 1 file changed, 14 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/ipack/devices/ipoctal.c |
| +++ b/drivers/ipack/devices/ipoctal.c |
| @@ -266,7 +266,6 @@ static int ipoctal_inst_slot(struct ipoc |
| int res; |
| int i; |
| struct tty_driver *tty; |
| - char name[20]; |
| struct ipoctal_channel *channel; |
| struct ipack_region *region; |
| void __iomem *addr; |
| @@ -357,8 +356,11 @@ static int ipoctal_inst_slot(struct ipoc |
| /* Fill struct tty_driver with ipoctal data */ |
| tty->owner = THIS_MODULE; |
| tty->driver_name = KBUILD_MODNAME; |
| - sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); |
| - tty->name = name; |
| + tty->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); |
| + if (!tty->name) { |
| + res = -ENOMEM; |
| + goto err_put_driver; |
| + } |
| tty->major = 0; |
| |
| tty->minor_start = 0; |
| @@ -374,8 +376,7 @@ static int ipoctal_inst_slot(struct ipoc |
| res = tty_register_driver(tty); |
| if (res) { |
| dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); |
| - put_tty_driver(tty); |
| - return res; |
| + goto err_free_name; |
| } |
| |
| /* Save struct tty_driver for use it when uninstalling the device */ |
| @@ -412,6 +413,13 @@ static int ipoctal_inst_slot(struct ipoc |
| ipoctal_irq_handler, ipoctal); |
| |
| return 0; |
| + |
| +err_free_name: |
| + kfree(tty->name); |
| +err_put_driver: |
| + put_tty_driver(tty); |
| + |
| + return res; |
| } |
| |
| static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, |
| @@ -700,6 +708,7 @@ static void __ipoctal_remove(struct ipoc |
| } |
| |
| tty_unregister_driver(ipoctal->tty_drv); |
| + kfree(ipoctal->tty_drv->name); |
| put_tty_driver(ipoctal->tty_drv); |
| kfree(ipoctal); |
| } |