aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ioctl.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:38:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit8f520021837d45c47d0ab57e7271f8d88bf7f3a4 (patch)
tree4435f3141163480c23f7274c502d58e3cd9cb963 /drivers/char/tty_ioctl.c
parent1d65b4a088de407e99714fdc27862449db04fb5c (diff)
tty: Termios locking - sort out real_tty confusions and lock reads
This moves us towards sanity and should mean our termios locking is now complete and comprehensive. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_ioctl.c')
-rw-r--r--drivers/char/tty_ioctl.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 93bfa1d6cc92..30670851e51a 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -893,6 +893,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
893{ 893{
894 struct tty_struct *real_tty; 894 struct tty_struct *real_tty;
895 void __user *p = (void __user *)arg; 895 void __user *p = (void __user *)arg;
896 int ret = 0;
896 897
897 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 898 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
898 tty->driver->subtype == PTY_TYPE_MASTER) 899 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -928,18 +929,24 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
928 return set_termios(real_tty, p, TERMIOS_OLD); 929 return set_termios(real_tty, p, TERMIOS_OLD);
929#ifndef TCGETS2 930#ifndef TCGETS2
930 case TCGETS: 931 case TCGETS:
932 mutex_lock(&real_tty->termios_mutex);
931 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) 933 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
932 return -EFAULT; 934 ret = -EFAULT;
933 return 0; 935 mutex_unlock(&real_tty->termios_mutex);
936 return ret;
934#else 937#else
935 case TCGETS: 938 case TCGETS:
939 mutex_lock(&real_tty->termios_mutex);
936 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) 940 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
937 return -EFAULT; 941 ret = -EFAULT;
938 return 0; 942 mutex_unlock(&real_tty->termios_mutex);
943 return ret;
939 case TCGETS2: 944 case TCGETS2:
945 mutex_lock(&real_tty->termios_mutex);
940 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) 946 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
941 return -EFAULT; 947 ret = -EFAULT;
942 return 0; 948 mutex_unlock(&real_tty->termios_mutex);
949 return ret;
943 case TCSETSF2: 950 case TCSETSF2:
944 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 951 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
945 case TCSETSW2: 952 case TCSETSW2:
@@ -957,36 +964,46 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
957 return set_termios(real_tty, p, TERMIOS_TERMIO); 964 return set_termios(real_tty, p, TERMIOS_TERMIO);
958#ifndef TCGETS2 965#ifndef TCGETS2
959 case TIOCGLCKTRMIOS: 966 case TIOCGLCKTRMIOS:
967 mutex_lock(&real_tty->termios_mutex);
960 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) 968 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
961 return -EFAULT; 969 ret = -EFAULT;
962 return 0; 970 mutex_unlock(&real_tty->termios_mutex);
971 return ret;
963 case TIOCSLCKTRMIOS: 972 case TIOCSLCKTRMIOS:
964 if (!capable(CAP_SYS_ADMIN)) 973 if (!capable(CAP_SYS_ADMIN))
965 return -EPERM; 974 return -EPERM;
975 mutex_lock(&real_tty->termios_mutex);
966 if (user_termios_to_kernel_termios(real_tty->termios_locked, 976 if (user_termios_to_kernel_termios(real_tty->termios_locked,
967 (struct termios __user *) arg)) 977 (struct termios __user *) arg))
968 return -EFAULT; 978 ret = -EFAULT;
969 return 0; 979 mutex_unlock(&real_tty->termios_mutex);
980 return ret;
970#else 981#else
971 case TIOCGLCKTRMIOS: 982 case TIOCGLCKTRMIOS:
983 mutex_lock(&real_tty->termios_mutex);
972 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) 984 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
973 return -EFAULT; 985 ret = -EFAULT;
974 return 0; 986 mutex_unlock(&real_tty->termios_mutex);
987 return ret;
975 case TIOCSLCKTRMIOS: 988 case TIOCSLCKTRMIOS:
976 if (!capable(CAP_SYS_ADMIN)) 989 if (!capable(CAP_SYS_ADMIN))
977 return -EPERM; 990 ret = -EPERM;
991 mutex_lock(&real_tty->termios_mutex);
978 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, 992 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
979 (struct termios __user *) arg)) 993 (struct termios __user *) arg))
980 return -EFAULT; 994 ret = -EFAULT;
981 return 0; 995 mutex_unlock(&real_tty->termios_mutex);
996 return ret;
982#endif 997#endif
983#ifdef TCGETX 998#ifdef TCGETX
984 case TCGETX: 999 case TCGETX:
985 if (real_tty->termiox == NULL) 1000 if (real_tty->termiox == NULL)
986 return -EINVAL; 1001 return -EINVAL;
1002 mutex_lock(&real_tty->termios_mutex);
987 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox))) 1003 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
988 return -EFAULT; 1004 ret = -EFAULT;
989 return 0; 1005 mutex_unlock(&real_tty->termios_mutex);
1006 return ret;
990 case TCSETX: 1007 case TCSETX:
991 return set_termiox(real_tty, p, 0); 1008 return set_termiox(real_tty, p, 0);
992 case TCSETXW: 1009 case TCSETXW:
@@ -995,10 +1012,11 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
995 return set_termiox(real_tty, p, TERMIOS_FLUSH); 1012 return set_termiox(real_tty, p, TERMIOS_FLUSH);
996#endif 1013#endif
997 case TIOCGSOFTCAR: 1014 case TIOCGSOFTCAR:
998 /* FIXME: for correctness we may need to take the termios 1015 mutex_lock(&real_tty->termios_mutex);
999 lock here - review */ 1016 ret = put_user(C_CLOCAL(real_tty) ? 1 : 0,
1000 return put_user(C_CLOCAL(real_tty) ? 1 : 0,
1001 (int __user *)arg); 1017 (int __user *)arg);
1018 mutex_unlock(&real_tty->termios_mutex);
1019 return ret;
1002 case TIOCSSOFTCAR: 1020 case TIOCSSOFTCAR:
1003 if (get_user(arg, (unsigned int __user *) arg)) 1021 if (get_user(arg, (unsigned int __user *) arg))
1004 return -EFAULT; 1022 return -EFAULT;