Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1613085

[PATCH 1/3] tty: close race between device register and open

From Johan Hovold <johan@kernel.org>
Newsgroups linux.kernel
Subject [PATCH 1/3] tty: close race between device register and open
Date 2017-03-30 15:50 +0200
Message-ID <tqICC-74s-19@gated-at.bofh.it> (permalink)
References <tqICB-74s-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


The tty class device is currently not registered until after the
character device has been registered thereby leaving a small window
were a racing open could end up with a NULL tty->dev pointer due to the
class-device lookup failing in alloc_tty_struct.

Close this race by registering the class device before the character
device while making sure to defer the user-space uevent notification
until after the character device has been registered.

Note that some tty drivers expect a valid tty->dev and would misbehave
or crash otherwise. Some line disciplines also currently dereference the
class device unconditionally despite the fact that not every tty is
guaranteed to have one (Unix98 pty), but this is being fixed separately.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/tty/tty_io.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index de4543ee290b..8e9651579d50 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3293,9 +3293,8 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
 {
 	char name[64];
 	dev_t devt = MKDEV(driver->major, driver->minor_start) + index;
-	struct device *dev = NULL;
-	int retval = -ENODEV;
-	bool cdev = false;
+	struct device *dev;
+	int retval;
 
 	if (index >= driver->num) {
 		pr_err("%s: Attempt to register invalid tty line number (%d)\n",
@@ -3308,18 +3307,9 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
 	else
 		tty_line_name(driver, index, name);
 
-	if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
-		retval = tty_cdev_add(driver, devt, index, 1);
-		if (retval)
-			goto error;
-		cdev = true;
-	}
-
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) {
-		retval = -ENOMEM;
-		goto error;
-	}
+	if (!dev)
+		return ERR_PTR(-ENOMEM);
 
 	dev->devt = devt;
 	dev->class = tty_class;
@@ -3329,18 +3319,28 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
 	dev->groups = attr_grp;
 	dev_set_drvdata(dev, drvdata);
 
+	dev_set_uevent_suppress(dev, 1);
+
 	retval = device_register(dev);
 	if (retval)
-		goto error;
+		goto err_put;
+
+	if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
+		retval = tty_cdev_add(driver, devt, index, 1);
+		if (retval)
+			goto err_del;
+	}
+
+	dev_set_uevent_suppress(dev, 0);
+	kobject_uevent(&dev->kobj, KOBJ_ADD);
 
 	return dev;
 
-error:
+err_del:
+	device_del(dev);
+err_put:
 	put_device(dev);
-	if (cdev) {
-		cdev_del(driver->cdevs[index]);
-		driver->cdevs[index] = NULL;
-	}
+
 	return ERR_PTR(retval);
 }
 EXPORT_SYMBOL_GPL(tty_register_device_attr);
-- 
2.12.2

Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 0/3] tty: close registration race and add termios reset feature Johan Hovold <johan@kernel.org> - 2017-03-30 15:50 +0200
  [PATCH 1/3] tty: close race between device register and open Johan Hovold <johan@kernel.org> - 2017-03-30 15:50 +0200
  [PATCH 2/3] tty: drop obsolete termios_locked comments Johan Hovold <johan@kernel.org> - 2017-03-30 15:50 +0200
  Re: [PATCH 0/3] tty: close registration race and add termios reset  feature Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-31 15:10 +0200

csiph-web