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 b0452688308c..97ebc8c5864e 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);
@@ -1358,9 +1405,7 @@ static int tty_reopen(struct tty_struct *tty)
1358 } 1405 }
1359 tty->count++; 1406 tty->count++;
1360 1407
1361 mutex_lock(&tty->ldisc_mutex);
1362 WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); 1408 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
1363 mutex_unlock(&tty->ldisc_mutex);
1364 1409
1365 return 0; 1410 return 0;
1366} 1411}
@@ -1477,6 +1522,17 @@ void tty_free_termios(struct tty_struct *tty)
1477} 1522}
1478EXPORT_SYMBOL(tty_free_termios); 1523EXPORT_SYMBOL(tty_free_termios);
1479 1524
1525/**
1526 * tty_flush_works - flush all works of a tty
1527 * @tty: tty device to flush works for
1528 *
1529 * Sync flush all works belonging to @tty.
1530 */
1531static void tty_flush_works(struct tty_struct *tty)
1532{
1533 flush_work(&tty->SAK_work);
1534 flush_work(&tty->hangup_work);
1535}
1480 1536
1481/** 1537/**
1482 * release_one_tty - release tty structure memory 1538 * release_one_tty - release tty structure memory
@@ -1562,6 +1618,7 @@ static void release_tty(struct tty_struct *tty, int idx)
1562 tty_free_termios(tty); 1618 tty_free_termios(tty);
1563 tty_driver_remove_tty(tty->driver, tty); 1619 tty_driver_remove_tty(tty->driver, tty);
1564 tty->port->itty = NULL; 1620 tty->port->itty = NULL;
1621 cancel_work_sync(&tty->port->buf.work);
1565 1622
1566 if (tty->link) 1623 if (tty->link)
1567 tty_kref_put(tty->link); 1624 tty_kref_put(tty->link);
@@ -1791,12 +1848,21 @@ int tty_release(struct inode *inode, struct file *filp)
1791 return 0; 1848 return 0;
1792 1849
1793#ifdef TTY_DEBUG_HANGUP 1850#ifdef TTY_DEBUG_HANGUP
1794 printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); 1851 printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf));
1795#endif 1852#endif
1796 /* 1853 /*
1797 * Ask the line discipline code to release its structures 1854 * Ask the line discipline code to release its structures
1798 */ 1855 */
1799 tty_ldisc_release(tty, o_tty); 1856 tty_ldisc_release(tty, o_tty);
1857
1858 /* Wait for pending work before tty destruction commmences */
1859 tty_flush_works(tty);
1860 if (o_tty)
1861 tty_flush_works(o_tty);
1862
1863#ifdef TTY_DEBUG_HANGUP
1864 printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf));
1865#endif
1800 /* 1866 /*
1801 * The release_tty function takes care of the details of clearing 1867 * The release_tty function takes care of the details of clearing
1802 * the slots and preserving the termios structure. The tty_unlock_pair 1868 * the slots and preserving the termios structure. The tty_unlock_pair