aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c170
1 files changed, 118 insertions, 52 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 05400acbc456..cbf5a5040908 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -533,6 +533,60 @@ void tty_wakeup(struct tty_struct *tty)
533EXPORT_SYMBOL_GPL(tty_wakeup); 533EXPORT_SYMBOL_GPL(tty_wakeup);
534 534
535/** 535/**
536 * tty_signal_session_leader - sends SIGHUP to session leader
537 * @tty controlling tty
538 * @exit_session if non-zero, signal all foreground group processes
539 *
540 * Send SIGHUP and SIGCONT to the session leader and its process group.
541 * Optionally, signal all processes in the foreground process group.
542 *
543 * Returns the number of processes in the session with this tty
544 * as their controlling terminal. This value is used to drop
545 * tty references for those processes.
546 */
547static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
548{
549 struct task_struct *p;
550 int refs = 0;
551 struct pid *tty_pgrp = NULL;
552
553 read_lock(&tasklist_lock);
554 if (tty->session) {
555 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
556 spin_lock_irq(&p->sighand->siglock);
557 if (p->signal->tty == tty) {
558 p->signal->tty = NULL;
559 /* We defer the dereferences outside fo
560 the tasklist lock */
561 refs++;
562 }
563 if (!p->signal->leader) {
564 spin_unlock_irq(&p->sighand->siglock);
565 continue;
566 }
567 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
568 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
569 put_pid(p->signal->tty_old_pgrp); /* A noop */
570 spin_lock(&tty->ctrl_lock);
571 tty_pgrp = get_pid(tty->pgrp);
572 if (tty->pgrp)
573 p->signal->tty_old_pgrp = get_pid(tty->pgrp);
574 spin_unlock(&tty->ctrl_lock);
575 spin_unlock_irq(&p->sighand->siglock);
576 } while_each_pid_task(tty->session, PIDTYPE_SID, p);
577 }
578 read_unlock(&tasklist_lock);
579
580 if (tty_pgrp) {
581 if (exit_session)
582 kill_pgrp(tty_pgrp, SIGHUP, exit_session);
583 put_pid(tty_pgrp);
584 }
585
586 return refs;
587}
588
589/**
536 * __tty_hangup - actual handler for hangup events 590 * __tty_hangup - actual handler for hangup events
537 * @work: tty device 591 * @work: tty device
538 * 592 *
@@ -554,15 +608,13 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
554 * tasklist_lock to walk task list for hangup event 608 * tasklist_lock to walk task list for hangup event
555 * ->siglock to protect ->signal/->sighand 609 * ->siglock to protect ->signal/->sighand
556 */ 610 */
557static void __tty_hangup(struct tty_struct *tty) 611static void __tty_hangup(struct tty_struct *tty, int exit_session)
558{ 612{
559 struct file *cons_filp = NULL; 613 struct file *cons_filp = NULL;
560 struct file *filp, *f = NULL; 614 struct file *filp, *f = NULL;
561 struct task_struct *p;
562 struct tty_file_private *priv; 615 struct tty_file_private *priv;
563 int closecount = 0, n; 616 int closecount = 0, n;
564 unsigned long flags; 617 int refs;
565 int refs = 0;
566 618
567 if (!tty) 619 if (!tty)
568 return; 620 return;
@@ -599,39 +651,18 @@ static void __tty_hangup(struct tty_struct *tty)
599 } 651 }
600 spin_unlock(&tty_files_lock); 652 spin_unlock(&tty_files_lock);
601 653
654 refs = tty_signal_session_leader(tty, exit_session);
655 /* Account for the p->signal references we killed */
656 while (refs--)
657 tty_kref_put(tty);
658
602 /* 659 /*
603 * it drops BTM and thus races with reopen 660 * it drops BTM and thus races with reopen
604 * we protect the race by TTY_HUPPING 661 * we protect the race by TTY_HUPPING
605 */ 662 */
606 tty_ldisc_hangup(tty); 663 tty_ldisc_hangup(tty);
607 664
608 read_lock(&tasklist_lock); 665 spin_lock_irq(&tty->ctrl_lock);
609 if (tty->session) {
610 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
611 spin_lock_irq(&p->sighand->siglock);
612 if (p->signal->tty == tty) {
613 p->signal->tty = NULL;
614 /* We defer the dereferences outside fo
615 the tasklist lock */
616 refs++;
617 }
618 if (!p->signal->leader) {
619 spin_unlock_irq(&p->sighand->siglock);
620 continue;
621 }
622 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
623 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
624 put_pid(p->signal->tty_old_pgrp); /* A noop */
625 spin_lock_irqsave(&tty->ctrl_lock, flags);
626 if (tty->pgrp)
627 p->signal->tty_old_pgrp = get_pid(tty->pgrp);
628 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
629 spin_unlock_irq(&p->sighand->siglock);
630 } while_each_pid_task(tty->session, PIDTYPE_SID, p);
631 }
632 read_unlock(&tasklist_lock);
633
634 spin_lock_irqsave(&tty->ctrl_lock, flags);
635 clear_bit(TTY_THROTTLED, &tty->flags); 666 clear_bit(TTY_THROTTLED, &tty->flags);
636 clear_bit(TTY_PUSH, &tty->flags); 667 clear_bit(TTY_PUSH, &tty->flags);
637 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 668 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
@@ -640,11 +671,7 @@ static void __tty_hangup(struct tty_struct *tty)
640 tty->session = NULL; 671 tty->session = NULL;
641 tty->pgrp = NULL; 672 tty->pgrp = NULL;
642 tty->ctrl_status = 0; 673 tty->ctrl_status = 0;
643 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 674 spin_unlock_irq(&tty->ctrl_lock);
644
645 /* Account for the p->signal references we killed */
646 while (refs--)
647 tty_kref_put(tty);
648 675
649 /* 676 /*
650 * If one of the devices matches a console pointer, we 677 * If one of the devices matches a console pointer, we
@@ -666,7 +693,6 @@ static void __tty_hangup(struct tty_struct *tty)
666 */ 693 */
667 set_bit(TTY_HUPPED, &tty->flags); 694 set_bit(TTY_HUPPED, &tty->flags);
668 clear_bit(TTY_HUPPING, &tty->flags); 695 clear_bit(TTY_HUPPING, &tty->flags);
669 tty_ldisc_enable(tty);
670 696
671 tty_unlock(tty); 697 tty_unlock(tty);
672 698
@@ -679,7 +705,7 @@ static void do_tty_hangup(struct work_struct *work)
679 struct tty_struct *tty = 705 struct tty_struct *tty =
680 container_of(work, struct tty_struct, hangup_work); 706 container_of(work, struct tty_struct, hangup_work);
681 707
682 __tty_hangup(tty); 708 __tty_hangup(tty, 0);
683} 709}
684 710
685/** 711/**
@@ -717,7 +743,7 @@ void tty_vhangup(struct tty_struct *tty)
717 743
718 printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); 744 printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
719#endif 745#endif
720 __tty_hangup(tty); 746 __tty_hangup(tty, 0);
721} 747}
722 748
723EXPORT_SYMBOL(tty_vhangup); 749EXPORT_SYMBOL(tty_vhangup);
@@ -741,6 +767,27 @@ void tty_vhangup_self(void)
741} 767}
742 768
743/** 769/**
770 * tty_vhangup_session - hangup session leader exit
771 * @tty: tty to hangup
772 *
773 * The session leader is exiting and hanging up its controlling terminal.
774 * Every process in the foreground process group is signalled SIGHUP.
775 *
776 * We do this synchronously so that when the syscall returns the process
777 * is complete. That guarantee is necessary for security reasons.
778 */
779
780static void tty_vhangup_session(struct tty_struct *tty)
781{
782#ifdef TTY_DEBUG_HANGUP
783 char buf[64];
784
785 printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf));
786#endif
787 __tty_hangup(tty, 1);
788}
789
790/**
744 * tty_hung_up_p - was tty hung up 791 * tty_hung_up_p - was tty hung up
745 * @filp: file pointer of tty 792 * @filp: file pointer of tty
746 * 793 *
@@ -797,18 +844,18 @@ void disassociate_ctty(int on_exit)
797 844
798 tty = get_current_tty(); 845 tty = get_current_tty();
799 if (tty) { 846 if (tty) {
800 struct pid *tty_pgrp = get_pid(tty->pgrp); 847 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) {
801 if (on_exit) { 848 tty_vhangup_session(tty);
802 if (tty->driver->type != TTY_DRIVER_TYPE_PTY) 849 } else {
803 tty_vhangup(tty); 850 struct pid *tty_pgrp = tty_get_pgrp(tty);
804 } 851 if (tty_pgrp) {
805 tty_kref_put(tty); 852 kill_pgrp(tty_pgrp, SIGHUP, on_exit);
806 if (tty_pgrp) {
807 kill_pgrp(tty_pgrp, SIGHUP, on_exit);
808 if (!on_exit)
809 kill_pgrp(tty_pgrp, SIGCONT, on_exit); 853 kill_pgrp(tty_pgrp, SIGCONT, on_exit);
810 put_pid(tty_pgrp); 854 put_pid(tty_pgrp);
855 }
811 } 856 }
857 tty_kref_put(tty);
858
812 } else if (on_exit) { 859 } else if (on_exit) {
813 struct pid *old_pgrp; 860 struct pid *old_pgrp;
814 spin_lock_irq(&current->sighand->siglock); 861 spin_lock_irq(&current->sighand->siglock);
@@ -1344,9 +1391,7 @@ static int tty_reopen(struct tty_struct *tty)
1344 } 1391 }
1345 tty->count++; 1392 tty->count++;
1346 1393
1347 mutex_lock(&tty->ldisc_mutex);
1348 WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); 1394 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
1349 mutex_unlock(&tty->ldisc_mutex);
1350 1395
1351 return 0; 1396 return 0;
1352} 1397}
@@ -1463,6 +1508,17 @@ void tty_free_termios(struct tty_struct *tty)
1463} 1508}
1464EXPORT_SYMBOL(tty_free_termios); 1509EXPORT_SYMBOL(tty_free_termios);
1465 1510
1511/**
1512 * tty_flush_works - flush all works of a tty
1513 * @tty: tty device to flush works for
1514 *
1515 * Sync flush all works belonging to @tty.
1516 */
1517static void tty_flush_works(struct tty_struct *tty)
1518{
1519 flush_work(&tty->SAK_work);
1520 flush_work(&tty->hangup_work);
1521}
1466 1522
1467/** 1523/**
1468 * release_one_tty - release tty structure memory 1524 * release_one_tty - release tty structure memory
@@ -1548,6 +1604,7 @@ static void release_tty(struct tty_struct *tty, int idx)
1548 tty_free_termios(tty); 1604 tty_free_termios(tty);
1549 tty_driver_remove_tty(tty->driver, tty); 1605 tty_driver_remove_tty(tty->driver, tty);
1550 tty->port->itty = NULL; 1606 tty->port->itty = NULL;
1607 cancel_work_sync(&tty->port->buf.work);
1551 1608
1552 if (tty->link) 1609 if (tty->link)
1553 tty_kref_put(tty->link); 1610 tty_kref_put(tty->link);
@@ -1777,12 +1834,21 @@ int tty_release(struct inode *inode, struct file *filp)
1777 return 0; 1834 return 0;
1778 1835
1779#ifdef TTY_DEBUG_HANGUP 1836#ifdef TTY_DEBUG_HANGUP
1780 printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); 1837 printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf));
1781#endif 1838#endif
1782 /* 1839 /*
1783 * Ask the line discipline code to release its structures 1840 * Ask the line discipline code to release its structures
1784 */ 1841 */
1785 tty_ldisc_release(tty, o_tty); 1842 tty_ldisc_release(tty, o_tty);
1843
1844 /* Wait for pending work before tty destruction commmences */
1845 tty_flush_works(tty);
1846 if (o_tty)
1847 tty_flush_works(o_tty);
1848
1849#ifdef TTY_DEBUG_HANGUP
1850 printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf));
1851#endif
1786 /* 1852 /*
1787 * The release_tty function takes care of the details of clearing 1853 * The release_tty function takes care of the details of clearing
1788 * the slots and preserving the termios structure. The tty_unlock_pair 1854 * the slots and preserving the termios structure. The tty_unlock_pair