aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-03-02 09:59:20 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 14:10:27 -0500
commit4001d7b7fc271052ebff43f327c26dc64806bbdf (patch)
tree0ed1daaf95b5e1e7ce73589b4b25e88ac0b60461
parentedab558feba1e2826ae8d65506168d7ccea7aad9 (diff)
vt: push down the tty lock so we can see what is left to tackle
At this point we have the tty_lock guarding a couple of oddities, plus the translation and unimap still. We also extend the console_lock in a couple of spots where coverage is wrong and switch vcs_open to use the right lock ! [Fixed the locking issue Jiri reported] Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/vt/vc_screen.c4
-rw-r--r--drivers/tty/vt/vt_ioctl.c92
2 files changed, 59 insertions, 37 deletions
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 7a367ff5122b..fa7268a93c06 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -608,10 +608,10 @@ vcs_open(struct inode *inode, struct file *filp)
608 unsigned int currcons = iminor(inode) & 127; 608 unsigned int currcons = iminor(inode) & 127;
609 int ret = 0; 609 int ret = 0;
610 610
611 tty_lock(); 611 console_lock();
612 if(currcons && !vc_cons_allocated(currcons-1)) 612 if(currcons && !vc_cons_allocated(currcons-1))
613 ret = -ENXIO; 613 ret = -ENXIO;
614 tty_unlock(); 614 console_unlock();
615 return ret; 615 return ret;
616} 616}
617 617
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 28ca0aa8664f..e05094d76344 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -281,7 +281,6 @@ int vt_ioctl(struct tty_struct *tty,
281 281
282 console = vc->vc_num; 282 console = vc->vc_num;
283 283
284 tty_lock();
285 284
286 if (!vc_cons_allocated(console)) { /* impossible? */ 285 if (!vc_cons_allocated(console)) { /* impossible? */
287 ret = -ENOIOCTLCMD; 286 ret = -ENOIOCTLCMD;
@@ -299,16 +298,18 @@ int vt_ioctl(struct tty_struct *tty,
299 298
300 switch (cmd) { 299 switch (cmd) {
301 case TIOCLINUX: 300 case TIOCLINUX:
301 tty_lock();
302 ret = tioclinux(tty, arg); 302 ret = tioclinux(tty, arg);
303 tty_unlock();
303 break; 304 break;
304 case KIOCSOUND: 305 case KIOCSOUND:
305 if (!perm) 306 if (!perm)
306 goto eperm; 307 return -EPERM;
307 /* 308 /*
308 * The use of PIT_TICK_RATE is historic, it used to be 309 * The use of PIT_TICK_RATE is historic, it used to be
309 * the platform-dependent CLOCK_TICK_RATE between 2.6.12 310 * the platform-dependent CLOCK_TICK_RATE between 2.6.12
310 * and 2.6.36, which was a minor but unfortunate ABI 311 * and 2.6.36, which was a minor but unfortunate ABI
311 * change. 312 * change. kd_mksound is locked by the input layer.
312 */ 313 */
313 if (arg) 314 if (arg)
314 arg = PIT_TICK_RATE / arg; 315 arg = PIT_TICK_RATE / arg;
@@ -317,7 +318,7 @@ int vt_ioctl(struct tty_struct *tty,
317 318
318 case KDMKTONE: 319 case KDMKTONE:
319 if (!perm) 320 if (!perm)
320 goto eperm; 321 return -EPERM;
321 { 322 {
322 unsigned int ticks, count; 323 unsigned int ticks, count;
323 324
@@ -335,7 +336,7 @@ int vt_ioctl(struct tty_struct *tty,
335 336
336 case KDGKBTYPE: 337 case KDGKBTYPE:
337 /* 338 /*
338 * this is naive. 339 * this is naïve.
339 */ 340 */
340 ucval = KB_101; 341 ucval = KB_101;
341 ret = put_user(ucval, (char __user *)arg); 342 ret = put_user(ucval, (char __user *)arg);
@@ -353,6 +354,8 @@ int vt_ioctl(struct tty_struct *tty,
353 /* 354 /*
354 * KDADDIO and KDDELIO may be able to add ports beyond what 355 * KDADDIO and KDDELIO may be able to add ports beyond what
355 * we reject here, but to be safe... 356 * we reject here, but to be safe...
357 *
358 * These are locked internally via sys_ioperm
356 */ 359 */
357 if (arg < GPFIRST || arg > GPLAST) { 360 if (arg < GPFIRST || arg > GPLAST) {
358 ret = -EINVAL; 361 ret = -EINVAL;
@@ -375,7 +378,7 @@ int vt_ioctl(struct tty_struct *tty,
375 struct kbd_repeat kbrep; 378 struct kbd_repeat kbrep;
376 379
377 if (!capable(CAP_SYS_TTY_CONFIG)) 380 if (!capable(CAP_SYS_TTY_CONFIG))
378 goto eperm; 381 return -EPERM;
379 382
380 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { 383 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
381 ret = -EFAULT; 384 ret = -EFAULT;
@@ -399,7 +402,7 @@ int vt_ioctl(struct tty_struct *tty,
399 * need to restore their engine state. --BenH 402 * need to restore their engine state. --BenH
400 */ 403 */
401 if (!perm) 404 if (!perm)
402 goto eperm; 405 return -EPERM;
403 switch (arg) { 406 switch (arg) {
404 case KD_GRAPHICS: 407 case KD_GRAPHICS:
405 break; 408 break;
@@ -412,6 +415,7 @@ int vt_ioctl(struct tty_struct *tty,
412 ret = -EINVAL; 415 ret = -EINVAL;
413 goto out; 416 goto out;
414 } 417 }
418 /* FIXME: this needs the console lock extending */
415 if (vc->vc_mode == (unsigned char) arg) 419 if (vc->vc_mode == (unsigned char) arg)
416 break; 420 break;
417 vc->vc_mode = (unsigned char) arg; 421 vc->vc_mode = (unsigned char) arg;
@@ -443,7 +447,7 @@ int vt_ioctl(struct tty_struct *tty,
443 447
444 case KDSKBMODE: 448 case KDSKBMODE:
445 if (!perm) 449 if (!perm)
446 goto eperm; 450 return -EPERM;
447 ret = vt_do_kdskbmode(console, arg); 451 ret = vt_do_kdskbmode(console, arg);
448 if (ret == 0) 452 if (ret == 0)
449 tty_ldisc_flush(tty); 453 tty_ldisc_flush(tty);
@@ -512,7 +516,7 @@ int vt_ioctl(struct tty_struct *tty,
512 case KDSIGACCEPT: 516 case KDSIGACCEPT:
513 { 517 {
514 if (!perm || !capable(CAP_KILL)) 518 if (!perm || !capable(CAP_KILL))
515 goto eperm; 519 return -EPERM;
516 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) 520 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
517 ret = -EINVAL; 521 ret = -EINVAL;
518 else { 522 else {
@@ -530,7 +534,7 @@ int vt_ioctl(struct tty_struct *tty,
530 struct vt_mode tmp; 534 struct vt_mode tmp;
531 535
532 if (!perm) 536 if (!perm)
533 goto eperm; 537 return -EPERM;
534 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { 538 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
535 ret = -EFAULT; 539 ret = -EFAULT;
536 goto out; 540 goto out;
@@ -576,6 +580,7 @@ int vt_ioctl(struct tty_struct *tty,
576 struct vt_stat __user *vtstat = up; 580 struct vt_stat __user *vtstat = up;
577 unsigned short state, mask; 581 unsigned short state, mask;
578 582
583 /* Review: FIXME: Console lock ? */
579 if (put_user(fg_console + 1, &vtstat->v_active)) 584 if (put_user(fg_console + 1, &vtstat->v_active))
580 ret = -EFAULT; 585 ret = -EFAULT;
581 else { 586 else {
@@ -593,6 +598,7 @@ int vt_ioctl(struct tty_struct *tty,
593 * Returns the first available (non-opened) console. 598 * Returns the first available (non-opened) console.
594 */ 599 */
595 case VT_OPENQRY: 600 case VT_OPENQRY:
601 /* FIXME: locking ? - but then this is a stupid API */
596 for (i = 0; i < MAX_NR_CONSOLES; ++i) 602 for (i = 0; i < MAX_NR_CONSOLES; ++i)
597 if (! VT_IS_IN_USE(i)) 603 if (! VT_IS_IN_USE(i))
598 break; 604 break;
@@ -606,7 +612,7 @@ int vt_ioctl(struct tty_struct *tty,
606 */ 612 */
607 case VT_ACTIVATE: 613 case VT_ACTIVATE:
608 if (!perm) 614 if (!perm)
609 goto eperm; 615 return -EPERM;
610 if (arg == 0 || arg > MAX_NR_CONSOLES) 616 if (arg == 0 || arg > MAX_NR_CONSOLES)
611 ret = -ENXIO; 617 ret = -ENXIO;
612 else { 618 else {
@@ -625,7 +631,7 @@ int vt_ioctl(struct tty_struct *tty,
625 struct vt_setactivate vsa; 631 struct vt_setactivate vsa;
626 632
627 if (!perm) 633 if (!perm)
628 goto eperm; 634 return -EPERM;
629 635
630 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, 636 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
631 sizeof(struct vt_setactivate))) { 637 sizeof(struct vt_setactivate))) {
@@ -653,6 +659,7 @@ int vt_ioctl(struct tty_struct *tty,
653 if (ret) 659 if (ret)
654 break; 660 break;
655 /* Commence switch and lock */ 661 /* Commence switch and lock */
662 /* Review set_console locks */
656 set_console(vsa.console); 663 set_console(vsa.console);
657 } 664 }
658 break; 665 break;
@@ -663,11 +670,14 @@ int vt_ioctl(struct tty_struct *tty,
663 */ 670 */
664 case VT_WAITACTIVE: 671 case VT_WAITACTIVE:
665 if (!perm) 672 if (!perm)
666 goto eperm; 673 return -EPERM;
667 if (arg == 0 || arg > MAX_NR_CONSOLES) 674 if (arg == 0 || arg > MAX_NR_CONSOLES)
668 ret = -ENXIO; 675 ret = -ENXIO;
669 else 676 else {
677 tty_lock();
670 ret = vt_waitactive(arg); 678 ret = vt_waitactive(arg);
679 tty_unlock();
680 }
671 break; 681 break;
672 682
673 /* 683 /*
@@ -682,16 +692,17 @@ int vt_ioctl(struct tty_struct *tty,
682 */ 692 */
683 case VT_RELDISP: 693 case VT_RELDISP:
684 if (!perm) 694 if (!perm)
685 goto eperm; 695 return -EPERM;
686 696
697 console_lock();
687 if (vc->vt_mode.mode != VT_PROCESS) { 698 if (vc->vt_mode.mode != VT_PROCESS) {
699 console_unlock();
688 ret = -EINVAL; 700 ret = -EINVAL;
689 break; 701 break;
690 } 702 }
691 /* 703 /*
692 * Switching-from response 704 * Switching-from response
693 */ 705 */
694 console_lock();
695 if (vc->vt_newvt >= 0) { 706 if (vc->vt_newvt >= 0) {
696 if (arg == 0) 707 if (arg == 0)
697 /* 708 /*
@@ -768,7 +779,7 @@ int vt_ioctl(struct tty_struct *tty,
768 779
769 ushort ll,cc; 780 ushort ll,cc;
770 if (!perm) 781 if (!perm)
771 goto eperm; 782 return -EPERM;
772 if (get_user(ll, &vtsizes->v_rows) || 783 if (get_user(ll, &vtsizes->v_rows) ||
773 get_user(cc, &vtsizes->v_cols)) 784 get_user(cc, &vtsizes->v_cols))
774 ret = -EFAULT; 785 ret = -EFAULT;
@@ -779,6 +790,7 @@ int vt_ioctl(struct tty_struct *tty,
779 790
780 if (vc) { 791 if (vc) {
781 vc->vc_resize_user = 1; 792 vc->vc_resize_user = 1;
793 /* FIXME: review v tty lock */
782 vc_resize(vc_cons[i].d, cc, ll); 794 vc_resize(vc_cons[i].d, cc, ll);
783 } 795 }
784 } 796 }
@@ -792,7 +804,7 @@ int vt_ioctl(struct tty_struct *tty,
792 struct vt_consize __user *vtconsize = up; 804 struct vt_consize __user *vtconsize = up;
793 ushort ll,cc,vlin,clin,vcol,ccol; 805 ushort ll,cc,vlin,clin,vcol,ccol;
794 if (!perm) 806 if (!perm)
795 goto eperm; 807 return -EPERM;
796 if (!access_ok(VERIFY_READ, vtconsize, 808 if (!access_ok(VERIFY_READ, vtconsize,
797 sizeof(struct vt_consize))) { 809 sizeof(struct vt_consize))) {
798 ret = -EFAULT; 810 ret = -EFAULT;
@@ -848,7 +860,7 @@ int vt_ioctl(struct tty_struct *tty,
848 860
849 case PIO_FONT: { 861 case PIO_FONT: {
850 if (!perm) 862 if (!perm)
851 goto eperm; 863 return -EPERM;
852 op.op = KD_FONT_OP_SET; 864 op.op = KD_FONT_OP_SET;
853 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ 865 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
854 op.width = 8; 866 op.width = 8;
@@ -889,7 +901,7 @@ int vt_ioctl(struct tty_struct *tty,
889 case PIO_FONTRESET: 901 case PIO_FONTRESET:
890 { 902 {
891 if (!perm) 903 if (!perm)
892 goto eperm; 904 return -EPERM;
893 905
894#ifdef BROKEN_GRAPHICS_PROGRAMS 906#ifdef BROKEN_GRAPHICS_PROGRAMS
895 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default 907 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
@@ -915,7 +927,7 @@ int vt_ioctl(struct tty_struct *tty,
915 break; 927 break;
916 } 928 }
917 if (!perm && op.op != KD_FONT_OP_GET) 929 if (!perm && op.op != KD_FONT_OP_GET)
918 goto eperm; 930 return -EPERM;
919 ret = con_font_op(vc, &op); 931 ret = con_font_op(vc, &op);
920 if (ret) 932 if (ret)
921 break; 933 break;
@@ -927,50 +939,65 @@ int vt_ioctl(struct tty_struct *tty,
927 case PIO_SCRNMAP: 939 case PIO_SCRNMAP:
928 if (!perm) 940 if (!perm)
929 ret = -EPERM; 941 ret = -EPERM;
930 else 942 else {
943 tty_lock();
931 ret = con_set_trans_old(up); 944 ret = con_set_trans_old(up);
945 tty_unlock();
946 }
932 break; 947 break;
933 948
934 case GIO_SCRNMAP: 949 case GIO_SCRNMAP:
950 tty_lock();
935 ret = con_get_trans_old(up); 951 ret = con_get_trans_old(up);
952 tty_unlock();
936 break; 953 break;
937 954
938 case PIO_UNISCRNMAP: 955 case PIO_UNISCRNMAP:
939 if (!perm) 956 if (!perm)
940 ret = -EPERM; 957 ret = -EPERM;
941 else 958 else {
959 tty_lock();
942 ret = con_set_trans_new(up); 960 ret = con_set_trans_new(up);
961 tty_unlock();
962 }
943 break; 963 break;
944 964
945 case GIO_UNISCRNMAP: 965 case GIO_UNISCRNMAP:
966 tty_lock();
946 ret = con_get_trans_new(up); 967 ret = con_get_trans_new(up);
968 tty_unlock();
947 break; 969 break;
948 970
949 case PIO_UNIMAPCLR: 971 case PIO_UNIMAPCLR:
950 { struct unimapinit ui; 972 { struct unimapinit ui;
951 if (!perm) 973 if (!perm)
952 goto eperm; 974 return -EPERM;
953 ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); 975 ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
954 if (ret) 976 if (ret)
955 ret = -EFAULT; 977 ret = -EFAULT;
956 else 978 else {
979 tty_lock();
957 con_clear_unimap(vc, &ui); 980 con_clear_unimap(vc, &ui);
981 tty_unlock();
982 }
958 break; 983 break;
959 } 984 }
960 985
961 case PIO_UNIMAP: 986 case PIO_UNIMAP:
962 case GIO_UNIMAP: 987 case GIO_UNIMAP:
988 tty_lock();
963 ret = do_unimap_ioctl(cmd, up, perm, vc); 989 ret = do_unimap_ioctl(cmd, up, perm, vc);
990 tty_unlock();
964 break; 991 break;
965 992
966 case VT_LOCKSWITCH: 993 case VT_LOCKSWITCH:
967 if (!capable(CAP_SYS_TTY_CONFIG)) 994 if (!capable(CAP_SYS_TTY_CONFIG))
968 goto eperm; 995 return -EPERM;
969 vt_dont_switch = 1; 996 vt_dont_switch = 1;
970 break; 997 break;
971 case VT_UNLOCKSWITCH: 998 case VT_UNLOCKSWITCH:
972 if (!capable(CAP_SYS_TTY_CONFIG)) 999 if (!capable(CAP_SYS_TTY_CONFIG))
973 goto eperm; 1000 return -EPERM;
974 vt_dont_switch = 0; 1001 vt_dont_switch = 0;
975 break; 1002 break;
976 case VT_GETHIFONTMASK: 1003 case VT_GETHIFONTMASK:
@@ -984,11 +1011,7 @@ int vt_ioctl(struct tty_struct *tty,
984 ret = -ENOIOCTLCMD; 1011 ret = -ENOIOCTLCMD;
985 } 1012 }
986out: 1013out:
987 tty_unlock();
988 return ret; 1014 return ret;
989eperm:
990 ret = -EPERM;
991 goto out;
992} 1015}
993 1016
994void reset_vc(struct vc_data *vc) 1017void reset_vc(struct vc_data *vc)
@@ -1150,8 +1173,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
1150 1173
1151 console = vc->vc_num; 1174 console = vc->vc_num;
1152 1175
1153 tty_lock();
1154
1155 if (!vc_cons_allocated(console)) { /* impossible? */ 1176 if (!vc_cons_allocated(console)) { /* impossible? */
1156 ret = -ENOIOCTLCMD; 1177 ret = -ENOIOCTLCMD;
1157 goto out; 1178 goto out;
@@ -1180,7 +1201,9 @@ long vt_compat_ioctl(struct tty_struct *tty,
1180 1201
1181 case PIO_UNIMAP: 1202 case PIO_UNIMAP:
1182 case GIO_UNIMAP: 1203 case GIO_UNIMAP:
1204 tty_lock();
1183 ret = compat_unimap_ioctl(cmd, up, perm, vc); 1205 ret = compat_unimap_ioctl(cmd, up, perm, vc);
1206 tty_unlock();
1184 break; 1207 break;
1185 1208
1186 /* 1209 /*
@@ -1217,11 +1240,9 @@ long vt_compat_ioctl(struct tty_struct *tty,
1217 goto fallback; 1240 goto fallback;
1218 } 1241 }
1219out: 1242out:
1220 tty_unlock();
1221 return ret; 1243 return ret;
1222 1244
1223fallback: 1245fallback:
1224 tty_unlock();
1225 return vt_ioctl(tty, cmd, arg); 1246 return vt_ioctl(tty, cmd, arg);
1226} 1247}
1227 1248
@@ -1407,6 +1428,7 @@ int vt_move_to_console(unsigned int vt, int alloc)
1407 return -EIO; 1428 return -EIO;
1408 } 1429 }
1409 console_unlock(); 1430 console_unlock();
1431 /* Review: I don't see why we need tty_lock here FIXME */
1410 tty_lock(); 1432 tty_lock();
1411 if (vt_waitactive(vt + 1)) { 1433 if (vt_waitactive(vt + 1)) {
1412 pr_debug("Suspend: Can't switch VCs."); 1434 pr_debug("Suspend: Can't switch VCs.");