- 06 Nov, 2014 40 commits
-
-
Peter Hurley authored
Eliminate the requirement of specifying the tty lock nesting at lock time; instead, set the lock subclass for slave ptys at pty install (normal ttys and master ptys use subclass 0). Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
When releasing the master pty, the slave pty also needs to be locked to prevent concurrent tty count changes for the slave pty and to ensure that only one parallel master and slave release observe the final close, and proceed to destruct the pty pair. Conversely, when releasing the slave pty, locking the master pty is not necessary (since the master's state can be inferred by the slave tty count). Introduce tty_lock_slave()/tty_unlock_slave() which acquires/releases the tty lock of the slave pty. Remove tty_lock_pair()/tty_unlock_pair(). Dropping the tty_lock is no longer required to re-establish a stable lock order. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The local o_tty variable in tty_release() is now accessed only when closing the pty master. Set o_tty to slave pty when closing pty master, otherwise NULL; use o_tty != NULL as replacement for pty_master. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Passing the 'other' tty to tty_release_checks() only makes sense for a pty pair; make o_tty scope local instead. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Passing the 'other' tty to tty_ldisc_release() only makes sense for a pty pair; make o_tty function local instead. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Perform work flush for both ends of a pty pair within tty_flush_works(), rather than calling twice. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
When the slave side closes and its tty count is 0, the pty pair can be destroyed; the master side must have already closed for the slave side tty count to be 0. Thus, only the pty master close must check if the slave side has closed by checking the slave tty count. Remove the pre-computed closing flags and check the actual count(s). Regular ttys are unaffected by this change. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Holding the tty_lock() is necessary to prevent concurrent changes to the tty count that may cause it to differ from the open file list count. The tty_lock() is already held at all call sites. NB: Note that the check for the pty master tty count is safe because the slave's tty_lock() is held while decrementing the pty master tty count. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Releasing the tty locks while waiting for the tty wait queues to be empty is no longer necessary nor desirable. Prior to "tty: Don't take tty_mutex for tty count changes", dropping the tty locks was necessary to reestablish the correct lock order between tty_mutex and the tty locks. Dropping the global tty_mutex was necessary; otherwise new ttys could not have been opened while waiting. However, without needing the global tty_mutex held, the tty locks for the releasing tty can now be held through the sleep. The sanity check is for abnormal conditions caused by kernel bugs, not for recoverable errors caused by misbehaving userspace; dropping the tty locks only allows the tty state to get more sideways. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Holding tty_mutex is no longer required to serialize changes to the tty_count or to prevent concurrent opens of closing ttys; tty_lock() is sufficient. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Now that re-open is not permitted for a legacy BSD pty master, using TTY_CLOSING to indicate when a tty can be torn-down is no longer necessary. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Holding tty_mutex for a tty re-open is no longer necessary since "tty: Clarify re-open behavior of master ptys". Because the slave tty count is no longer accessed by tty_reopen(), holding tty_mutex to prevent concurrent final tty_release() of the slave pty is not required. As with "tty: Re-open /dev/tty without tty_mutex", holding a tty kref until the tty_lock is acquired is sufficient to ensure the tty has not been freed, which, in turn, is sufficient to ensure the tty_lock can be safely acquired and the tty count can be safely retrieved. A non-zero tty count with the tty lock held guarantees that release_tty() has not run and cannot run concurrently with tty_reopen(). Change tty_driver_lookup_tty() to acquire the tty kref, which allows the tty_mutex to be dropped before acquiring the tty lock. Dropping the tty_mutex before attempting the tty_lock allows other ttys to be opened and released, without needing this tty_reopen() to complete. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Opening /dev/tty (ie., the controlling tty for the current task) is always a re-open of the underlying tty. Because holding the tty_lock is sufficient for safely re-opening a tty, and because having a tty kref is sufficient for safely acquiring the tty_lock [1], tty_open_current_tty() does not require holding tty_mutex. Repurpose tty_open_current_tty() to perform the re-open itself and refactor tty_open(). [1] Analysis of safely re-opening the current tty w/o tty_mutex get_current_tty() gets a tty kref from the already kref'ed tty value of current->signal->tty while holding the sighand lock for the current task. This guarantees that the tty pointer returned from get_current_tty() points to a tty which remains referenceable while holding the kref. Although release_tty() may run concurrently, and thus the driver reference may be removed, release_one_tty() cannot have run, and won't while holding the tty kref. This, in turn, guarantees the tty_lock() can safely be acquired (since tty->magic and tty->legacy_mutex are still a valid dereferences). The tty_lock() also gets a tty kref to prevent the tty_unlock() from dereferencing a released tty. Thus, the kref returned from get_current_tty() can be released. Lastly, the first operation of tty_reopen() is to check the tty count. If non-zero, this ensures release_tty() is not running concurrently, and the driver references have not been removed. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Opening the slave BSD pty first already returns -EIO from the slave pty_open(), which in turn causes the newly installed tty pair to be released before returning from tty_open(). However, this can also cause a parallel master BSD pty open to fail because the pty pair destruction may already been taking place in tty_release(). Failing at driver->install() if the slave pty is opened first ensures that a pty master open cannot fail, because the driver tables will not have been updated so tty_driver_lookup_tty() won't find the master pty (and attempt to "re-open" it). In turn, this guarantees that any tty with a tty->count == 0 is in final close (rather than never opened). Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Although perhaps not obvious, the TTY_CLOSING bit is set when the tty count has been decremented to 0 (which occurs while holding tty_lock). The only other case when tty count is 0 during a re-open is when a legacy BSD pty master has been opened in parallel but after the pty slave, which is unsupported and returns an error. Thus !tty->count contains the complete set of degenerate conditions under which a tty open fails. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Re-opening master ptys is not allowed. Once opened and for the remaining lifetime of the master pty, its tty count is 1. If its tty count has dropped to 0, then the master pty was closed and TTY_CLOSING was set, and destruction may begin imminently. Besides the normal case of a legacy BSD pty master being re-opened (which always returns -EIO), this code is only reachable in 2 degenerate cases: 1. The pty master is the controlling terminal (this is possible through the TIOCSCTTY ioctl). pty masters are not designed to be controlling terminals and it's an oversight that tiocsctty() ever let that happen. The attempted open of /dev/tty will always fail. No known program does this. 2. The legacy BSD pty slave was opened first. The slave open will fail in pty_open() and tty_release() will commence. But before tty_release() claims the tty_mutex, there is a very small window where a parallel master open might succeed. In a test of racing legacy BSD slave and master parallel opens, where: slave open attempts: 10000 success:4527 failure:5473 master open attempts: 11728 success:5789 failure:5939 only 8 master open attempts would have succeeded reaching this code and successfully opened the master pty. This case is not possible with SysV ptys. Always return -EIO if a master pty is re-opened or the slave is opened first and the master opened in parallel (for legacy BSD ptys). Furthermore, now that changing the slave's count is not required, the tty_lock is sufficient for preventing concurrent changes to the tty being re-opened (or failing re-opening). Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Now that tty_ldisc_hangup() does not drop the tty lock, it is no longer possible to observe TTY_HUPPING while holding the tty lock on another cpu. Remove TTY_HUPPING bit definition. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Dropping the tty lock to acquire the tty->ldisc_sem allows several race conditions (such as hangup while changing the ldisc) which requires extra states and testing. The ldisc_sem->tty_lock lock order has not been required since tty buffer ownership was moved to tty_port. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The tty->ldisc_sem write lock is sufficient for serializing changes to tty->ldisc; holding the tty lock is not required. Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Mike Skoog authored
Added recognition of EndRun Technologies PCIe PTP slave card and setup two ttySx ports for communication with the card for retrieval of PTP based time and to communicate with the card's Linux OS. Signed-off-by:
Mike Skoog <mskoog@endruntechnologies.com> Signed-off-by:
Mike Korreng <mkorreng@endruntechnologies.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The stale comment refers to lock behavior which was eliminated in commit 6d76bd26, n_tty: Make N_TTY ldisc receive path lockless. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Packet mode can only be set for a pty master, and a pty master is always in raw mode since its termios cannot be changed. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The pty master read() can miss the wake up for a packet mode status change. For example, CPU 0 | CPU 1 n_tty_read() | n_tty_packet_mode_flush() ... | . if (packet & link->ctrl_status) { | . /* no new ctrl_status ATM */ | . | spin_lock | ctrl_status |= TIOCPKT_FLUSHREAD | spin_unlock | wake_up(link->read_wait) } | set_current_state(TASK_INTERRUPTIBLE) | ... | The pty master read() will now sleep (assuming there is no input) having missed the read_wait wakeup. Set the task state before the condition test. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Updates to the packet mode enable require holding the ctrl_lock; the serialization prevents corruption of adjacent fields. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Because pty_set_pktmode() does not claim the slave's ctrl_lock to clear ->ctrl_status (to avoid unnecessary lock nesting), pty_set_pktmode() may accidentally erase new ->ctrl_status updates. For example, CPU 0 | CPU 1 pty_set_pktmode() | pty_start() spin_lock(master's ctrl_lock) | tty->packet = 1 | | if (tty->link->packet) | spin_lock(slave's ctrl_lock) | tty->ctrl_status = TIOCPKT_START tty->link->ctrl_status = 0 | Ensure the clear of ->ctrl_status occurs before packet mode is set (and observable on another cpu). Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The slave's ctrl_lock serializes updates to the ctrl_status field only, whereas the master's ctrl_lock serializes updates to the packet mode enable (ie., the master does not have ctrl_status and the slave does not have packet mode). Thus, claiming the slave's ctrl_lock to access ->packet is useless. Unlocked reads of ->packet are already smp-safe. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Interrupts are enabled in the n_tty_read() loop, ioctl(TIOCPKT) and pty driver flush_buffer() routine; no need to save and restore local interrupt state. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The tty driver's set_termios() method is called with interrupts enabled; there is no need to save and restore the local interrupt state. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Packet mode is unique to the pty driver; move the packet mode state change code from the generic tty ioctl handler to the pty driver. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The pty master's termios should never be set; currently, all code paths which call the driver's set_termios() method ensure that the pty slave's termios is being set. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The session and foreground process group pid references will be non-NULL if tiocsctty() is stealing the controlling tty from another session (ie., arg == 1 in tiocsctty()). Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Setting the controlling terminal for a session occurs with either the first open of a non-pty master tty or with ioctl(TIOCSCTTY). Since only the session leader can set the controlling terminal for a session (and the session leader cannot change), it is not necessary to prevent a process from attempting to set different ttys as the controlling terminal concurrently. So it's only necessary to prevent the same tty from becoming the controlling terminal for different session leaders. The tty_lock() is sufficient to prevent concurrent proc_set_tty() for the same tty. Remove the tty_mutex lock region; add tty_lock() to tiocsctty(). While this may appear to allow a race condition between opening the controlling tty via tty_open_current_tty() and stealing the controlling tty via ioctl(TIOCSCTTY, 1), that race condition already existed. Even if the tty_mutex prevented stealing the controlling tty while tty_open_current_tty() returned the original controlling tty, it cannot prevent stealing the controlling tty before tty_open() returns. Thus, tty_open() could already return a no-longer-controlling tty when opening /dev/tty. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
tiocspgrp() is the lone caller of session_of_pgrp(); relocate and limit to file scope. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Claim a read lock on the tasklist_lock while setting the controlling terminal for the session leader. This fixes multiple races: 1. task_pgrp() and task_session() cannot be safely dereferenced, such as passing to get_pid(), without holding either rcu_read_lock() or tasklist_lock 2. setsid() unwisely allows any thread in the thread group to make the thread group leader the session leader; this makes the unlocked reads of ->signal->leader and signal->tty potentially unordered, stale or even have spurious values. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
The tty parameter to __proc_set_tty() cannot be NULL; all call sites have already dereferenced tty. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Replace open-coded instances of tty_get_pgrp(). Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Although the tty core maintains a pid reference for the foreground process group, if the foreground process group is changed that pid reference is dropped. Thus, the pid reference used for signalling could become stale. Safely obtain a pid reference to the foreground process group and release the reference after signalling is complete. cc: Jeff Dike <jdike@addtoit.com> Acked-by:
Richard Weinberger <richard@nod.at> Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Only the current task itself can set its controlling tty (other than before the task has been forked). Equivalent to existing usage. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
Move the controlling tty-related functions and remove forward declarations for __proc_set_tty() and proc_set_tty(). Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
Peter Hurley authored
tty_pair_get_pty() has no in-tree users and tty_pair_get_tty() has only one file-local user. Remove the external declarations, the export declarations, and declare tty_pair_get_tty() static. Signed-off-by:
Peter Hurley <peter@hurleysoftware.com> Reviewed-by:
Alan Cox <alan@linux.intel.com> Signed-off-by:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-