Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Jun 2012 14:14:49 +0000 (UTC)
From:      Peter Holm <pho@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r237780 - stable/8/sys/kern
Message-ID:  <201206291414.q5TEEnnn050111@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pho
Date: Fri Jun 29 14:14:49 2012
New Revision: 237780
URL: http://svn.freebsd.org/changeset/base/237780

Log:
  MFC: r237219
  
  In tty_makedev() the following construction:
  
  dev = make_dev_cred();
  dev->si_drv1 = tp;
  
  leaves a small window where the newly created device may be opened
  and si_drv1 is NULL.
  
  As this is a vary rare situation, using a lock to close the window
  seems overkill. Instead just wait for the assignment of si_drv1.

Modified:
  stable/8/sys/kern/tty.c
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/kern/tty.c
==============================================================================
--- stable/8/sys/kern/tty.c	Fri Jun 29 13:02:46 2012	(r237779)
+++ stable/8/sys/kern/tty.c	Fri Jun 29 14:14:49 2012	(r237780)
@@ -216,9 +216,15 @@ ttydev_leave(struct tty *tp)
 static int
 ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 {
-	struct tty *tp = dev->si_drv1;
+	struct tty *tp;
 	int error = 0;
 
+	while ((tp = dev->si_drv1) == NULL) {
+		error = tsleep(&dev->si_drv1, PCATCH, "ttdrv1", 1);
+		if (error != EWOULDBLOCK)
+			return (error);
+	}
+
 	tty_lock(tp);
 	if (tty_gone(tp)) {
 		/* Device is already gone. */
@@ -726,9 +732,14 @@ static struct cdevsw ttydev_cdevsw = {
 static int
 ttyil_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 {
-	struct tty *tp = dev->si_drv1;
+	struct tty *tp;
 	int error = 0;
 
+	while ((tp = dev->si_drv1) == NULL) {
+		error = tsleep(&dev->si_drv1, PCATCH, "ttdrv1", 1);
+		if (error != EWOULDBLOCK)
+			return (error);
+	}
 	tty_lock(tp);
 	if (tty_gone(tp))
 		error = ENODEV;
@@ -1166,6 +1177,7 @@ tty_makedev(struct tty *tp, struct ucred
 	dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
 	    uid, gid, mode, "%s%s", prefix, name);
 	dev->si_drv1 = tp;
+	wakeup(&dev->si_drv1);
 	tp->t_dev = dev;
 
 	/* Slave call-in devices. */
@@ -1174,12 +1186,14 @@ tty_makedev(struct tty *tp, struct ucred
 		    uid, gid, mode, "%s%s.init", prefix, name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
+		wakeup(&dev->si_drv1);
 		dev->si_drv2 = &tp->t_termios_init_in;
 
 		dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
 		    uid, gid, mode, "%s%s.lock", prefix, name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
+		wakeup(&dev->si_drv1);
 		dev->si_drv2 = &tp->t_termios_lock_in;
 	}
 
@@ -1189,6 +1203,7 @@ tty_makedev(struct tty *tp, struct ucred
 		    UID_UUCP, GID_DIALER, 0660, "cua%s", name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
+		wakeup(&dev->si_drv1);
 
 		/* Slave call-out devices. */
 		if (tp->t_flags & TF_INITLOCK) {
@@ -1196,12 +1211,14 @@ tty_makedev(struct tty *tp, struct ucred
 			    UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
 			dev_depends(tp->t_dev, dev);
 			dev->si_drv1 = tp;
+			wakeup(&dev->si_drv1);
 			dev->si_drv2 = &tp->t_termios_init_out;
 
 			dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
 			    UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
 			dev_depends(tp->t_dev, dev);
 			dev->si_drv1 = tp;
+			wakeup(&dev->si_drv1);
 			dev->si_drv2 = &tp->t_termios_lock_out;
 		}
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206291414.q5TEEnnn050111>