diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:40:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:41 -0400 |
commit | 2cb5998b5f0ccc886fdda3509059eef297b49577 (patch) | |
tree | 9113731d3f892c2e164bfd05a7cf1a4b1713a619 | |
parent | 216ba023a96c04e8d3aabf83d5931c35b6e2dbbb (diff) |
tty: the vhangup syscall is racy
We now have the infrastructure to sort this out but rather than teaching
the syscall tty lock rules we move the hard work into a tty helper
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/tty_io.c | 19 | ||||
-rw-r--r-- | fs/open.c | 3 | ||||
-rw-r--r-- | include/linux/tty.h | 1 |
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 913b50258f90..b5f57d0b30ee 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -730,6 +730,25 @@ void tty_vhangup(struct tty_struct *tty) | |||
730 | EXPORT_SYMBOL(tty_vhangup); | 730 | EXPORT_SYMBOL(tty_vhangup); |
731 | 731 | ||
732 | /** | 732 | /** |
733 | * tty_vhangup_self - process vhangup for own ctty | ||
734 | * | ||
735 | * Perform a vhangup on the current controlling tty | ||
736 | */ | ||
737 | |||
738 | void tty_vhangup_self(void) | ||
739 | { | ||
740 | struct tty_struct *tty; | ||
741 | |||
742 | mutex_lock(&tty_mutex); | ||
743 | tty = get_current_tty(); | ||
744 | if (tty) { | ||
745 | tty_vhangup(tty); | ||
746 | tty_kref_put(tty); | ||
747 | } | ||
748 | mutex_unlock(&tty_mutex); | ||
749 | } | ||
750 | |||
751 | /** | ||
733 | * tty_hung_up_p - was tty hung up | 752 | * tty_hung_up_p - was tty hung up |
734 | * @filp: file pointer of tty | 753 | * @filp: file pointer of tty |
735 | * | 754 | * |
@@ -1141,8 +1141,7 @@ EXPORT_SYMBOL(sys_close); | |||
1141 | asmlinkage long sys_vhangup(void) | 1141 | asmlinkage long sys_vhangup(void) |
1142 | { | 1142 | { |
1143 | if (capable(CAP_SYS_TTY_CONFIG)) { | 1143 | if (capable(CAP_SYS_TTY_CONFIG)) { |
1144 | /* XXX: this needs locking */ | 1144 | tty_vhangup_self(); |
1145 | tty_vhangup(current->signal->tty); | ||
1146 | return 0; | 1145 | return 0; |
1147 | } | 1146 | } |
1148 | return -EPERM; | 1147 | return -EPERM; |
diff --git a/include/linux/tty.h b/include/linux/tty.h index c30ed8d3bcbd..e00393a3d1c9 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -361,6 +361,7 @@ extern int is_ignored(int sig); | |||
361 | extern int tty_signal(int sig, struct tty_struct *tty); | 361 | extern int tty_signal(int sig, struct tty_struct *tty); |
362 | extern void tty_hangup(struct tty_struct *tty); | 362 | extern void tty_hangup(struct tty_struct *tty); |
363 | extern void tty_vhangup(struct tty_struct *tty); | 363 | extern void tty_vhangup(struct tty_struct *tty); |
364 | extern void tty_vhangup_self(void); | ||
364 | extern void tty_unhangup(struct file *filp); | 365 | extern void tty_unhangup(struct file *filp); |
365 | extern int tty_hung_up_p(struct file *filp); | 366 | extern int tty_hung_up_p(struct file *filp); |
366 | extern void do_SAK(struct tty_struct *tty); | 367 | extern void do_SAK(struct tty_struct *tty); |