open-controlling-tty — open a controlling terminal and prepare for login
open-controlling-tty is a chain-loading utility that opens a terminal as a controlling terminal, sets its own standard I/O file descriptors to it, and then chain loads to
next-prog with the execvp(3) function.
next-prog may contain its own command line options, which open-controlling-tty will ignore.
open-controlling-tty expects to inherit the terminal character device filename to open as the value of the
TTY environment variable, which it expects to have been set up by a program such as vc-get-tty(1) or pty-get-tty(1).
This can be either a virtual or a real terminal.
It opens this terminal, hangs up (or otherwise disassociates) any existing processes for which it was still a controlling terminal or which had open file handles to it; assigns it as its own controlling terminal; sets its own standard input, standard output, and standard error file descriptors to it (closing whatever they were previously open to); and then (if everything succeeds) chain loads
The standard file descriptors are duplicated from an open file descriptor to the terminal, which is opened in read+write mode. There is one underlying common file description.
open-controlling-tty does not call setsid(2) to become a session leader. On some operating systems it it necessary to already be a session leader in order to set a controlling terminal. On those operating systems, it is thus necessary to chain to open-controlling-tty from setsid(1).
open-controlling-tty does not make any attempt to adjust its process group or the foreground process group of the controlling terminal. Dealing with these is the province of a job-control shell, which may not even run as this process. (Linux login(1) with PAM runs the job-controlling shell as a child process, for example.)
If the --exclusive command line option is used, it will attempt to use the
TIOCEXCL ioctl(2) function to put the terminal device into "exclusive" mode.
If --vhangup command line option is used, which tells it to call the vhangup(2) system call, open-controlling-tty has to open the terminal device file twice, once so that it can disconnect/hangup existing processes, which of course disconnects itself at the same time, and once again to gain the controlling TTY afterwards. There is a race condition here, where the character device file could be unlinked or otherwise altered in between the two opens.
open-controlling-tty opens the terminal device file once, because BSD has no vhangup(2) system call. Instead, on BSD open-controlling-tty calls revoke(2) before opening the terminal device file, if the --revoke command line option is used. A similar race condition exists, except that it is between the call to revoke(2) and the call to then open(2) the terminal device file. Again, the character device file could be unlinked or otherwise altered in between the two.
To restrict the processes able to take advantage of these races to just those programs running as the current user or the superuser:
System administrators should ensure that the directory containing the character device file is not writable by untrusted accounts.
Programs that invoke open-controlling-tty should ensure that the character device file is owned by the effective UID of the process, and has
rw- permissions for that owner alone, no other user or group having any permissions.
The grantpt(3) library function does this for pseudo-terminals. pty-get-tty(1) calls this function; and vc-get-tty(1) performs the moral equivalent for virtual consoles. (On the BSDs, pseudo-terminal slave devices are created with these UID and permissions in the first place, and the library function is in fact a no-op.)
Programs that invoke open-controlling-tty should ensure that neither it nor any other program can open the character device file until the ownership has been properly set.
The unlockpt(3) library function does this for pseudo-terminals. pty-get-tty(1) calls this function. (On the BSDs, because grantpt(3) is a no-op, this is a no-op as well.) Unfortunately, there is no moral equivalent for kernel-supplied virtual consoles, and nothing that vc-get-tty(1) can do. However, userspace virtual consoles use pseudo-terminals and pty-get-tty(1).