home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / pty4 / part06 / CTTYS.draft1 < prev    next >
Encoding:
Text File  |  1992-02-18  |  9.2 KB  |  192 lines

  1. Controlling Ttys: A UNIX Horror Story
  2. Daniel J. Bernstein
  3. draft 1
  4. 10/6/91
  5.  
  6.  
  7. 1. Introduction
  8.  
  9.      ``Normal file access permissions handle security.''
  10.             ---POSIX.1-1988 rationale, B.7.1.1.4
  11.  
  12. When a user logs into a UNIX system, he is assigned a _tty_ which echoes
  13. and processes his characters, lets him edit command lines, handles flow
  14. control on output, and so on. The user's shell reads and writes from the
  15. tty. Messages sent by the ``write'' and ``talk'' user communication
  16. commands are also sent through the tty. In fact, ttys (also called
  17. _terminals_, _teletypes_, and _typewriters_) are the focal point of
  18. almost all interaction between a user and the system.
  19.  
  20. Ttys come in two flavors: hardwired ttys and pseudo-ttys. Hardwired ttys
  21. are connected directly to a physical device, such as a modem.
  22. Pseudo-ttys may be dynamically connected to any process. For instance,
  23. the telnetd program links a pseudo-tty with each network connection.
  24.  
  25. Unlike pipes, ttys have traditionally been assigned a name in the
  26. filesystem: /dev/console, for instance, is a hardwired tty, and
  27. /dev/ttyp7 is a pseudo-tty. The primary reason for these files is to
  28. support user-to-user communication. The system typically assigns
  29. ownership of tty files to the current user. That way the user can change
  30. his tty modes to control whether ``write'' and ``talk'' messages are
  31. allowed.
  32.  
  33. Occasionally a program (or more often a script) wants to send messages
  34. to the current tty, no matter what redirection has been put on stdout
  35. and stderr. (The author defers judgment on whether this is a sensible
  36. thing for programs to do.) More often, a user wants to know what the
  37. current tty is, to keep track of what he's doing. One obvious solution
  38. to both problems is to keep the current tty in an environment variable,
  39. like TTY=/dev/ttyp7. Then a ``tty'' program can simply echo $TTY, and
  40. programs which want to talk to the user can open $TTY.
  41.  
  42. Unfortunately, UNIX never acquired such a simple user-mode solution.
  43. Instead each process was assigned a ``controlling tty'', something which
  44. the kernel kept track of and treated specially. That is where the horror
  45. story begins.
  46.  
  47.  
  48. 2. Controlling ttys
  49.  
  50. Processes start without a controlling terminal. When a process without a
  51. controlling tty (also called ``ctty'') opens a tty, it is assigned that
  52. ctty, and the ctty is preserved through fork() and exec(). Different
  53. UNIX systems have various methods of removing the association between a
  54. process and its controlling tty. We will return to this subject below.
  55.  
  56. A special file, /dev/tty, is accessible to all processes at all times.
  57. When a process opens /dev/tty, it gets a valid descriptor to its ctty,
  58. or ENODEV if it does not have a ctty. The protection on the actual tty
  59. file is irrelevant to /dev/tty.
  60.  
  61. Under BSD 4.2, the controlling tty has almost no effects on job control.
  62. BSD 4.3 added some rules in the name of job control security. POSIX went
  63. much farther, and formalized controlling ttys into ``sessions.'' Each
  64. process is associated with a session, and various ad-hoc session rules
  65. are thrown in to complicate job control and signal processing in
  66. general. (For instance, a process can only stop if its parent is in the
  67. *same* session but a *different* process group.) The problem of
  68. supporting job control without losing security became an excuse for
  69. controlling terminals and sessions.
  70.  
  71. At this point we can identify six separate forms of access to a tty
  72. device, say /dev/ttyp7, by a process:
  73.  
  74.    O (ownership) access: uid owns /dev/ttyp7
  75.    P (protection) access: uid has permision to open /dev/ttyp7
  76.    C (ctty) access: current ctty is /dev/ttyp7
  77.    T (/dev/tty) access: file descriptor to /dev/tty, pointing to /dev/ttyp7
  78.    S (slave) access: file descriptor to /dev/ttyp7 itself
  79.    M (master) access: file descriptor to /dev/ptyp7 (pseudo-ttys only)
  80.  
  81. (The names ``master'' and ``slave'' are pseudo-tty terminology.)
  82. The system lets a process acquire access in several ways: A process with
  83. O access can gain P access. A process with P access can gain S access. A
  84. process with C access can gain T access. A process with M or S access
  85. can gain C access. A process can gain M access (by opening /dev/ptyp7)
  86. if no other process has M access.
  87.  
  88. Under BSD, to shed C access, a process must gain T access (i.e., open
  89. /dev/tty) and perform the TIOCNOTTY ioctl. Unfortunately, if any process
  90. applies the TIOCEXCL ioctl to the tty, no process will be able to open
  91. /dev/tty itself until some process does TIOCNXCL. A program stuck under
  92. a tty with TIOCEXCL set has *absolutely no reliable way* to dissociate
  93. itself from that tty. (Perhaps this is not a surprise given that there
  94. is also absolutely no reliable way for a process to figure out what tty
  95. it is associated with in the first place.)
  96.  
  97. And the TIOCEXCL problem pales beside the number of twists and turns
  98. introduced by POSIX. Obviously this is not a simple system to implement,
  99. use, understand, or make secure.
  100.  
  101.  
  102. 3. Security
  103.  
  104. Steve Bellovin pointed out years ago ([]), as did this author ([]), that
  105. an attacker could abuse controlling ttys to take almost complete control
  106. of the system. Put simply, it is very difficult to detect, let alone
  107. revoke, whether another user has S, T, or C access to a tty.
  108.  
  109. BSD 4.2 and its descendants have a vhangup() system call meant to revoke
  110. access to a tty. Unfortunately, it doesn't work on most systems, and
  111. only revokes S access on the rest. (This author considers vhangup() a
  112. joke in very poor taste.)
  113.  
  114. Several vendors have attempted to fix this problem. The Convex UNIX 8.0
  115. documentation, for instance, says that the holes are gone. They're not.
  116. Convex insisted that its system was secure until the author sent
  117. explicit code showing how to break tty security.
  118.  
  119. Similarly, after a series of Internet breakins using tty security holes,
  120. Sun distributed a patch to their SunOS 4.1 telnetd and rlogind
  121. supposedly fixing the problems ([]). (It is worth noting that
  122. essentially the same fix appeared in version 3.0 of the author's pty
  123. package [] several months before.) Although the patch was enough to
  124. temporarily stop the attacks, it did not close C access, and hence was
  125. not enough.
  126.  
  127. Version 4.0 of the author's pty package ([]) includes security tests
  128. which detect all possible forms of tty access, and which work on any BSD
  129. system. It is obscene that such measures have proven necessary. In the
  130. meantime, crackers from the Netherlands and elsewhere have broken into
  131. literally thousands of Internet accounts, taking advantage of tty
  132. security holes at will.
  133.  
  134.  
  135. 4. Simplifications
  136.  
  137. Under SunOS 4.1, BSD 4.4, and a few other systems, T access has been
  138. removed. A process which opens /dev/tty will get a full-fledged
  139. descriptor to /dev/ttyp7; there is no longer any distinction between
  140. /dev/tty and the real tty file it refers to, except that /dev/tty is
  141. always completely unprotected.
  142.  
  143. Any excuse for controlling terminals or POSIX sessions on the basis of
  144. job control security is completely invalid. As pointed out by the author
  145. in [], the job control system can be made much simpler, easier to use,
  146. and simultaneously completely secure, with absolutely no help from cttys
  147. or POSIX sessions. As suggested above, the controlling tty can be passed
  148. in the TTY environment variable. C (and T) access, as well as POSIX
  149. sessions, can simply disappear.
  150.  
  151. (Apparently the disappearance of cttys and POSIX sessions would remove
  152. absolutely no functionality, from either the user's or the application's
  153. point of view; and of course it would make a much cleaner system and
  154. standard if it were officially adopted. The author would greatly love to
  155. hear from any proponents of POSIX sessions who can explain what features
  156. they provide, especially in light of his new, simple, secure job control
  157. system, when in fact vendors, programmers, and users wouldn't care if
  158. setsid() became a no-op.)
  159.  
  160. For backwards compatibility it would be useful to keep a /dev/tty device
  161. so that programs do not have to be changed to use $TTY. Applications
  162. running under the author's pty program can normally access the tty
  163. through descriptor 3, so an easy solution here is to let /dev/tty be a
  164. simple driver which dup()s fd 3.
  165.  
  166. The only other useful function of a controlling terminal---viz., to help
  167. the user categorize processes---is easily taken care of at user level.
  168. ps can use $TTY for its output. Accounting could be by pid (as it should
  169. be) instead of by the marginally useful ac_tty.
  170.  
  171. We're still left with O and P access---ttys are still in the filesystem.
  172. Given fd 3 support, programs which want to talk to the user don't need
  173. to open() ttys. The other use of ttys in the filesystem is user-to-user
  174. communication, but there are several replacement communication systems
  175. which depend on users running their own daemons rather than having a
  176. writable tty file. So tty files can disappear. Rather than opening tty
  177. files, programs can create ttys with a new system call. Then ttys will
  178. be much more like pipes, which may be accessed only through a pair of
  179. descriptors.
  180.  
  181. If these simplifications had been made when UNIX was young, before it
  182. was used by millions of people, then maybe the controlling terminal
  183. horror story would not have lasted so long or caused so much damage.
  184. Fortunately, the story will end soon, as in October 1992 the author will
  185. distribute code which anyone can use to exploit these holes. Any vendor
  186. which wants to stay in business will fix its systems long before then.
  187.  
  188.  
  189. References
  190.  
  191. XXX
  192.