Skip to content

Commit 4001d7b

Browse files
Alan Coxgregkh
Alan Cox
authored andcommitted
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>
1 parent edab558 commit 4001d7b

File tree

2 files changed

+59
-37
lines changed

2 files changed

+59
-37
lines changed

drivers/tty/vt/vc_screen.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,10 @@ vcs_open(struct inode *inode, struct file *filp)
608608
unsigned int currcons = iminor(inode) & 127;
609609
int ret = 0;
610610

611-
tty_lock();
611+
console_lock();
612612
if(currcons && !vc_cons_allocated(currcons-1))
613613
ret = -ENXIO;
614-
tty_unlock();
614+
console_unlock();
615615
return ret;
616616
}
617617

drivers/tty/vt/vt_ioctl.c

+57-35
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ int vt_ioctl(struct tty_struct *tty,
281281

282282
console = vc->vc_num;
283283

284-
tty_lock();
285284

286285
if (!vc_cons_allocated(console)) { /* impossible? */
287286
ret = -ENOIOCTLCMD;
@@ -299,16 +298,18 @@ int vt_ioctl(struct tty_struct *tty,
299298

300299
switch (cmd) {
301300
case TIOCLINUX:
301+
tty_lock();
302302
ret = tioclinux(tty, arg);
303+
tty_unlock();
303304
break;
304305
case KIOCSOUND:
305306
if (!perm)
306-
goto eperm;
307+
return -EPERM;
307308
/*
308309
* The use of PIT_TICK_RATE is historic, it used to be
309310
* the platform-dependent CLOCK_TICK_RATE between 2.6.12
310311
* and 2.6.36, which was a minor but unfortunate ABI
311-
* change.
312+
* change. kd_mksound is locked by the input layer.
312313
*/
313314
if (arg)
314315
arg = PIT_TICK_RATE / arg;
@@ -317,7 +318,7 @@ int vt_ioctl(struct tty_struct *tty,
317318

318319
case KDMKTONE:
319320
if (!perm)
320-
goto eperm;
321+
return -EPERM;
321322
{
322323
unsigned int ticks, count;
323324

@@ -335,7 +336,7 @@ int vt_ioctl(struct tty_struct *tty,
335336

336337
case KDGKBTYPE:
337338
/*
338-
* this is naive.
339+
* this is naïve.
339340
*/
340341
ucval = KB_101;
341342
ret = put_user(ucval, (char __user *)arg);
@@ -353,6 +354,8 @@ int vt_ioctl(struct tty_struct *tty,
353354
/*
354355
* KDADDIO and KDDELIO may be able to add ports beyond what
355356
* we reject here, but to be safe...
357+
*
358+
* These are locked internally via sys_ioperm
356359
*/
357360
if (arg < GPFIRST || arg > GPLAST) {
358361
ret = -EINVAL;
@@ -375,7 +378,7 @@ int vt_ioctl(struct tty_struct *tty,
375378
struct kbd_repeat kbrep;
376379

377380
if (!capable(CAP_SYS_TTY_CONFIG))
378-
goto eperm;
381+
return -EPERM;
379382

380383
if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
381384
ret = -EFAULT;
@@ -399,7 +402,7 @@ int vt_ioctl(struct tty_struct *tty,
399402
* need to restore their engine state. --BenH
400403
*/
401404
if (!perm)
402-
goto eperm;
405+
return -EPERM;
403406
switch (arg) {
404407
case KD_GRAPHICS:
405408
break;
@@ -412,6 +415,7 @@ int vt_ioctl(struct tty_struct *tty,
412415
ret = -EINVAL;
413416
goto out;
414417
}
418+
/* FIXME: this needs the console lock extending */
415419
if (vc->vc_mode == (unsigned char) arg)
416420
break;
417421
vc->vc_mode = (unsigned char) arg;
@@ -443,7 +447,7 @@ int vt_ioctl(struct tty_struct *tty,
443447

444448
case KDSKBMODE:
445449
if (!perm)
446-
goto eperm;
450+
return -EPERM;
447451
ret = vt_do_kdskbmode(console, arg);
448452
if (ret == 0)
449453
tty_ldisc_flush(tty);
@@ -512,7 +516,7 @@ int vt_ioctl(struct tty_struct *tty,
512516
case KDSIGACCEPT:
513517
{
514518
if (!perm || !capable(CAP_KILL))
515-
goto eperm;
519+
return -EPERM;
516520
if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
517521
ret = -EINVAL;
518522
else {
@@ -530,7 +534,7 @@ int vt_ioctl(struct tty_struct *tty,
530534
struct vt_mode tmp;
531535

532536
if (!perm)
533-
goto eperm;
537+
return -EPERM;
534538
if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
535539
ret = -EFAULT;
536540
goto out;
@@ -576,6 +580,7 @@ int vt_ioctl(struct tty_struct *tty,
576580
struct vt_stat __user *vtstat = up;
577581
unsigned short state, mask;
578582

583+
/* Review: FIXME: Console lock ? */
579584
if (put_user(fg_console + 1, &vtstat->v_active))
580585
ret = -EFAULT;
581586
else {
@@ -593,6 +598,7 @@ int vt_ioctl(struct tty_struct *tty,
593598
* Returns the first available (non-opened) console.
594599
*/
595600
case VT_OPENQRY:
601+
/* FIXME: locking ? - but then this is a stupid API */
596602
for (i = 0; i < MAX_NR_CONSOLES; ++i)
597603
if (! VT_IS_IN_USE(i))
598604
break;
@@ -606,7 +612,7 @@ int vt_ioctl(struct tty_struct *tty,
606612
*/
607613
case VT_ACTIVATE:
608614
if (!perm)
609-
goto eperm;
615+
return -EPERM;
610616
if (arg == 0 || arg > MAX_NR_CONSOLES)
611617
ret = -ENXIO;
612618
else {
@@ -625,7 +631,7 @@ int vt_ioctl(struct tty_struct *tty,
625631
struct vt_setactivate vsa;
626632

627633
if (!perm)
628-
goto eperm;
634+
return -EPERM;
629635

630636
if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
631637
sizeof(struct vt_setactivate))) {
@@ -653,6 +659,7 @@ int vt_ioctl(struct tty_struct *tty,
653659
if (ret)
654660
break;
655661
/* Commence switch and lock */
662+
/* Review set_console locks */
656663
set_console(vsa.console);
657664
}
658665
break;
@@ -663,11 +670,14 @@ int vt_ioctl(struct tty_struct *tty,
663670
*/
664671
case VT_WAITACTIVE:
665672
if (!perm)
666-
goto eperm;
673+
return -EPERM;
667674
if (arg == 0 || arg > MAX_NR_CONSOLES)
668675
ret = -ENXIO;
669-
else
676+
else {
677+
tty_lock();
670678
ret = vt_waitactive(arg);
679+
tty_unlock();
680+
}
671681
break;
672682

673683
/*
@@ -682,16 +692,17 @@ int vt_ioctl(struct tty_struct *tty,
682692
*/
683693
case VT_RELDISP:
684694
if (!perm)
685-
goto eperm;
695+
return -EPERM;
686696

697+
console_lock();
687698
if (vc->vt_mode.mode != VT_PROCESS) {
699+
console_unlock();
688700
ret = -EINVAL;
689701
break;
690702
}
691703
/*
692704
* Switching-from response
693705
*/
694-
console_lock();
695706
if (vc->vt_newvt >= 0) {
696707
if (arg == 0)
697708
/*
@@ -768,7 +779,7 @@ int vt_ioctl(struct tty_struct *tty,
768779

769780
ushort ll,cc;
770781
if (!perm)
771-
goto eperm;
782+
return -EPERM;
772783
if (get_user(ll, &vtsizes->v_rows) ||
773784
get_user(cc, &vtsizes->v_cols))
774785
ret = -EFAULT;
@@ -779,6 +790,7 @@ int vt_ioctl(struct tty_struct *tty,
779790

780791
if (vc) {
781792
vc->vc_resize_user = 1;
793+
/* FIXME: review v tty lock */
782794
vc_resize(vc_cons[i].d, cc, ll);
783795
}
784796
}
@@ -792,7 +804,7 @@ int vt_ioctl(struct tty_struct *tty,
792804
struct vt_consize __user *vtconsize = up;
793805
ushort ll,cc,vlin,clin,vcol,ccol;
794806
if (!perm)
795-
goto eperm;
807+
return -EPERM;
796808
if (!access_ok(VERIFY_READ, vtconsize,
797809
sizeof(struct vt_consize))) {
798810
ret = -EFAULT;
@@ -848,7 +860,7 @@ int vt_ioctl(struct tty_struct *tty,
848860

849861
case PIO_FONT: {
850862
if (!perm)
851-
goto eperm;
863+
return -EPERM;
852864
op.op = KD_FONT_OP_SET;
853865
op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
854866
op.width = 8;
@@ -889,7 +901,7 @@ int vt_ioctl(struct tty_struct *tty,
889901
case PIO_FONTRESET:
890902
{
891903
if (!perm)
892-
goto eperm;
904+
return -EPERM;
893905

894906
#ifdef BROKEN_GRAPHICS_PROGRAMS
895907
/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
@@ -915,7 +927,7 @@ int vt_ioctl(struct tty_struct *tty,
915927
break;
916928
}
917929
if (!perm && op.op != KD_FONT_OP_GET)
918-
goto eperm;
930+
return -EPERM;
919931
ret = con_font_op(vc, &op);
920932
if (ret)
921933
break;
@@ -927,50 +939,65 @@ int vt_ioctl(struct tty_struct *tty,
927939
case PIO_SCRNMAP:
928940
if (!perm)
929941
ret = -EPERM;
930-
else
942+
else {
943+
tty_lock();
931944
ret = con_set_trans_old(up);
945+
tty_unlock();
946+
}
932947
break;
933948

934949
case GIO_SCRNMAP:
950+
tty_lock();
935951
ret = con_get_trans_old(up);
952+
tty_unlock();
936953
break;
937954

938955
case PIO_UNISCRNMAP:
939956
if (!perm)
940957
ret = -EPERM;
941-
else
958+
else {
959+
tty_lock();
942960
ret = con_set_trans_new(up);
961+
tty_unlock();
962+
}
943963
break;
944964

945965
case GIO_UNISCRNMAP:
966+
tty_lock();
946967
ret = con_get_trans_new(up);
968+
tty_unlock();
947969
break;
948970

949971
case PIO_UNIMAPCLR:
950972
{ struct unimapinit ui;
951973
if (!perm)
952-
goto eperm;
974+
return -EPERM;
953975
ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
954976
if (ret)
955977
ret = -EFAULT;
956-
else
978+
else {
979+
tty_lock();
957980
con_clear_unimap(vc, &ui);
981+
tty_unlock();
982+
}
958983
break;
959984
}
960985

961986
case PIO_UNIMAP:
962987
case GIO_UNIMAP:
988+
tty_lock();
963989
ret = do_unimap_ioctl(cmd, up, perm, vc);
990+
tty_unlock();
964991
break;
965992

966993
case VT_LOCKSWITCH:
967994
if (!capable(CAP_SYS_TTY_CONFIG))
968-
goto eperm;
995+
return -EPERM;
969996
vt_dont_switch = 1;
970997
break;
971998
case VT_UNLOCKSWITCH:
972999
if (!capable(CAP_SYS_TTY_CONFIG))
973-
goto eperm;
1000+
return -EPERM;
9741001
vt_dont_switch = 0;
9751002
break;
9761003
case VT_GETHIFONTMASK:
@@ -984,11 +1011,7 @@ int vt_ioctl(struct tty_struct *tty,
9841011
ret = -ENOIOCTLCMD;
9851012
}
9861013
out:
987-
tty_unlock();
9881014
return ret;
989-
eperm:
990-
ret = -EPERM;
991-
goto out;
9921015
}
9931016

9941017
void reset_vc(struct vc_data *vc)
@@ -1150,8 +1173,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
11501173

11511174
console = vc->vc_num;
11521175

1153-
tty_lock();
1154-
11551176
if (!vc_cons_allocated(console)) { /* impossible? */
11561177
ret = -ENOIOCTLCMD;
11571178
goto out;
@@ -1180,7 +1201,9 @@ long vt_compat_ioctl(struct tty_struct *tty,
11801201

11811202
case PIO_UNIMAP:
11821203
case GIO_UNIMAP:
1204+
tty_lock();
11831205
ret = compat_unimap_ioctl(cmd, up, perm, vc);
1206+
tty_unlock();
11841207
break;
11851208

11861209
/*
@@ -1217,11 +1240,9 @@ long vt_compat_ioctl(struct tty_struct *tty,
12171240
goto fallback;
12181241
}
12191242
out:
1220-
tty_unlock();
12211243
return ret;
12221244

12231245
fallback:
1224-
tty_unlock();
12251246
return vt_ioctl(tty, cmd, arg);
12261247
}
12271248

@@ -1407,6 +1428,7 @@ int vt_move_to_console(unsigned int vt, int alloc)
14071428
return -EIO;
14081429
}
14091430
console_unlock();
1431+
/* Review: I don't see why we need tty_lock here FIXME */
14101432
tty_lock();
14111433
if (vt_waitactive(vt + 1)) {
14121434
pr_debug("Suspend: Can't switch VCs.");

0 commit comments

Comments
 (0)