git: kernel - Attempt to fix tty race
Matthew Dillon
dillon at crater.dragonflybsd.org
Wed Oct 9 23:49:08 PDT 2013
commit a4adb7f3df4dc86dd0a73e2ac7cac1b1ad804355
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date: Wed Oct 9 23:34:13 2013 -0700
kernel - Attempt to fix tty race
* Opening /dev/tty is special cased to open the session ttyvp. The
VCTTYISOPEN flag is used on the session ttyvp to indicate this.
* There is a bug where the VCTTYISOPEN flag is set prior to calling
VOP_OPEN() on ttyvp. Because devfs's devfs_spec_open() (and
also devfs_spec_close()) temporarily release the vnode lock
on the vp (ttyvp in this case), setting the flag prior to
the VOP_OPEN() can lead to a race where another process opens
AND closes /dev/tty before our VOP_OPEN() executes.
The racing open will see that the VCTTYISOPEN flag is already
set and not issue a VOP_OPEN(). It's close will then VOP_CLOSE()
ttyvp (which so far has not been opened by either process),
which can kill the last open on ttyvp and cause the tty to
disconnect.
This race is very difficult to reproduce. We were only able to
reproduce it on monster (48-core opteron) which happened to
access "/dev/tty" during a poudriere bulk build in a manner
that was able to trigger the race.
* Fix this particular bug by not setting the VCTTYISOPEN flag
until after VOP_OPEN() returns, then re-checking the flag to
detect the race and clean-up/retry if a race is detected.
* TODO - This is not the only bug. Unfortunately it is also quite possible
for multiple threads/processes to open("/dev/tty", ...) simultaniously.
There is only one VCTTYISOPEN flag so when this occurs and one process
then close()s its descriptor, the VCTTYISOPEN flag is cleared.
The other process or processes may then proceed to access ttyvp without
an opencount guard. When they close() the count is handled properly
because the close() code detects that the VCTTYISOPEN flag was cleared.
The problem is the unguarded read, write, and ioctl calls that might
occur in the mean time.
Summary of changes:
sys/kern/tty_tty.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/a4adb7f3df4dc86dd0a73e2ac7cac1b1ad804355
--
DragonFly BSD source repository
More information about the Commits
mailing list