1
2
3
4
5
6
7
8
9
10
11
12#include <linux/types.h>
13#include <linux/errno.h>
14#include <linux/sched/signal.h>
15#include <linux/tty.h>
16#include <linux/timer.h>
17#include <linux/kernel.h>
18#include <linux/compat.h>
19#include <linux/module.h>
20#include <linux/kd.h>
21#include <linux/vt.h>
22#include <linux/string.h>
23#include <linux/slab.h>
24#include <linux/major.h>
25#include <linux/fs.h>
26#include <linux/console.h>
27#include <linux/consolemap.h>
28#include <linux/signal.h>
29#include <linux/suspend.h>
30#include <linux/timex.h>
31
32#include <asm/io.h>
33#include <linux/uaccess.h>
34
35#include <linux/nospec.h>
36
37#include <linux/kbd_kern.h>
38#include <linux/vt_kern.h>
39#include <linux/kbd_diacr.h>
40#include <linux/selection.h>
41
42bool vt_dont_switch;
43
44static inline bool vt_in_use(unsigned int i)
45{
46 const struct vc_data *vc = vc_cons[i].d;
47
48
49
50
51
52 WARN_CONSOLE_UNLOCKED();
53
54 return vc && kref_read(&vc->port.kref) > 1;
55}
56
57static inline bool vt_busy(int i)
58{
59 if (vt_in_use(i))
60 return true;
61 if (i == fg_console)
62 return true;
63 if (vc_is_sel(vc_cons[i].d))
64 return true;
65
66 return false;
67}
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82#ifdef CONFIG_X86
83#include <asm/syscalls.h>
84#endif
85
86static void complete_change_console(struct vc_data *vc);
87
88
89
90
91
92struct vt_event_wait {
93 struct list_head list;
94 struct vt_event event;
95 int done;
96};
97
98static LIST_HEAD(vt_events);
99static DEFINE_SPINLOCK(vt_event_lock);
100static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
101
102
103
104
105
106
107
108
109
110
111void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
112{
113 struct list_head *pos, *head;
114 unsigned long flags;
115 int wake = 0;
116
117 spin_lock_irqsave(&vt_event_lock, flags);
118 head = &vt_events;
119
120 list_for_each(pos, head) {
121 struct vt_event_wait *ve = list_entry(pos,
122 struct vt_event_wait, list);
123 if (!(ve->event.event & event))
124 continue;
125 ve->event.event = event;
126
127
128 ve->event.oldev = old + 1;
129 ve->event.newev = new + 1;
130 wake = 1;
131 ve->done = 1;
132 }
133 spin_unlock_irqrestore(&vt_event_lock, flags);
134 if (wake)
135 wake_up_interruptible(&vt_event_waitqueue);
136}
137
138static void __vt_event_queue(struct vt_event_wait *vw)
139{
140 unsigned long flags;
141
142 INIT_LIST_HEAD(&vw->list);
143 vw->done = 0;
144
145 spin_lock_irqsave(&vt_event_lock, flags);
146 list_add(&vw->list, &vt_events);
147 spin_unlock_irqrestore(&vt_event_lock, flags);
148}
149
150static void __vt_event_wait(struct vt_event_wait *vw)
151{
152
153 wait_event_interruptible(vt_event_waitqueue, vw->done);
154}
155
156static void __vt_event_dequeue(struct vt_event_wait *vw)
157{
158 unsigned long flags;
159
160
161 spin_lock_irqsave(&vt_event_lock, flags);
162 list_del(&vw->list);
163 spin_unlock_irqrestore(&vt_event_lock, flags);
164}
165
166
167
168
169
170
171
172
173
174
175static void vt_event_wait(struct vt_event_wait *vw)
176{
177 __vt_event_queue(vw);
178 __vt_event_wait(vw);
179 __vt_event_dequeue(vw);
180}
181
182
183
184
185
186
187
188
189static int vt_event_wait_ioctl(struct vt_event __user *event)
190{
191 struct vt_event_wait vw;
192
193 if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
194 return -EFAULT;
195
196 if (vw.event.event & ~VT_MAX_EVENT)
197 return -EINVAL;
198
199 vt_event_wait(&vw);
200
201 if (vw.done) {
202 if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
203 return -EFAULT;
204 return 0;
205 }
206 return -EINTR;
207}
208
209
210
211
212
213
214
215
216
217int vt_waitactive(int n)
218{
219 struct vt_event_wait vw;
220 do {
221 vw.event.event = VT_EVENT_SWITCH;
222 __vt_event_queue(&vw);
223 if (n == fg_console + 1) {
224 __vt_event_dequeue(&vw);
225 break;
226 }
227 __vt_event_wait(&vw);
228 __vt_event_dequeue(&vw);
229 if (vw.done == 0)
230 return -EINTR;
231 } while (vw.event.newev != n);
232 return 0;
233}
234
235
236
237
238
239#define GPFIRST 0x3b4
240#define GPLAST 0x3df
241#define GPNUM (GPLAST - GPFIRST + 1)
242
243
244
245
246
247
248
249
250static int vt_kdsetmode(struct vc_data *vc, unsigned long mode)
251{
252 switch (mode) {
253 case KD_GRAPHICS:
254 break;
255 case KD_TEXT0:
256 case KD_TEXT1:
257 mode = KD_TEXT;
258 fallthrough;
259 case KD_TEXT:
260 break;
261 default:
262 return -EINVAL;
263 }
264
265
266 if (vc->vc_mode == mode)
267 return 0;
268
269 vc->vc_mode = mode;
270 if (vc->vc_num != fg_console)
271 return 0;
272
273
274 console_lock();
275 if (mode == KD_TEXT)
276 do_unblank_screen(1);
277 else
278 do_blank_screen(1);
279 console_unlock();
280
281 return 0;
282}
283
284static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
285 unsigned long arg, bool perm)
286{
287 struct vc_data *vc = tty->driver_data;
288 void __user *up = (void __user *)arg;
289 unsigned int console = vc->vc_num;
290 int ret;
291
292 switch (cmd) {
293 case KIOCSOUND:
294 if (!perm)
295 return -EPERM;
296
297
298
299
300
301
302 if (arg)
303 arg = PIT_TICK_RATE / arg;
304 kd_mksound(arg, 0);
305 break;
306
307 case KDMKTONE:
308 if (!perm)
309 return -EPERM;
310 {
311 unsigned int ticks, count;
312
313
314
315
316
317 ticks = msecs_to_jiffies((arg >> 16) & 0xffff);
318 count = ticks ? (arg & 0xffff) : 0;
319 if (count)
320 count = PIT_TICK_RATE / count;
321 kd_mksound(count, ticks);
322 break;
323 }
324
325 case KDGKBTYPE:
326
327
328
329 return put_user(KB_101, (char __user *)arg);
330
331
332
333
334
335
336
337#ifdef CONFIG_X86
338 case KDADDIO:
339 case KDDELIO:
340
341
342
343
344
345
346 if (arg < GPFIRST || arg > GPLAST)
347 return -EINVAL;
348
349 return ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
350
351 case KDENABIO:
352 case KDDISABIO:
353 return ksys_ioperm(GPFIRST, GPNUM,
354 (cmd == KDENABIO)) ? -ENXIO : 0;
355#endif
356
357
358
359 case KDKBDREP:
360 {
361 struct kbd_repeat kbrep;
362
363 if (!capable(CAP_SYS_TTY_CONFIG))
364 return -EPERM;
365
366 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat)))
367 return -EFAULT;
368
369 ret = kbd_rate(&kbrep);
370 if (ret)
371 return ret;
372 if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
373 return -EFAULT;
374 break;
375 }
376
377 case KDSETMODE:
378 if (!perm)
379 return -EPERM;
380
381 return vt_kdsetmode(vc, arg);
382
383 case KDGETMODE:
384 return put_user(vc->vc_mode, (int __user *)arg);
385
386 case KDMAPDISP:
387 case KDUNMAPDISP:
388
389
390
391
392 return -EINVAL;
393
394 case KDSKBMODE:
395 if (!perm)
396 return -EPERM;
397 ret = vt_do_kdskbmode(console, arg);
398 if (ret)
399 return ret;
400 tty_ldisc_flush(tty);
401 break;
402
403 case KDGKBMODE:
404 return put_user(vt_do_kdgkbmode(console), (int __user *)arg);
405
406
407
408 case KDSKBMETA:
409 return vt_do_kdskbmeta(console, arg);
410
411 case KDGKBMETA:
412
413 return put_user(vt_do_kdgkbmeta(console), (int __user *)arg);
414
415 case KDGETKEYCODE:
416 case KDSETKEYCODE:
417 if(!capable(CAP_SYS_TTY_CONFIG))
418 perm = 0;
419 return vt_do_kbkeycode_ioctl(cmd, up, perm);
420
421 case KDGKBENT:
422 case KDSKBENT:
423 return vt_do_kdsk_ioctl(cmd, up, perm, console);
424
425 case KDGKBSENT:
426 case KDSKBSENT:
427 return vt_do_kdgkb_ioctl(cmd, up, perm);
428
429
430
431 case KDGKBDIACR:
432 case KDGKBDIACRUC:
433 case KDSKBDIACR:
434 case KDSKBDIACRUC:
435 return vt_do_diacrit(cmd, up, perm);
436
437
438
439 case KDGKBLED:
440 case KDSKBLED:
441 case KDGETLED:
442 case KDSETLED:
443 return vt_do_kdskled(console, cmd, arg, perm);
444
445
446
447
448
449
450
451
452 case KDSIGACCEPT:
453 if (!perm || !capable(CAP_KILL))
454 return -EPERM;
455 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
456 return -EINVAL;
457
458 spin_lock_irq(&vt_spawn_con.lock);
459 put_pid(vt_spawn_con.pid);
460 vt_spawn_con.pid = get_pid(task_pid(current));
461 vt_spawn_con.sig = arg;
462 spin_unlock_irq(&vt_spawn_con.lock);
463 break;
464
465 case KDFONTOP: {
466 struct console_font_op op;
467
468 if (copy_from_user(&op, up, sizeof(op)))
469 return -EFAULT;
470 if (!perm && op.op != KD_FONT_OP_GET)
471 return -EPERM;
472 ret = con_font_op(vc, &op);
473 if (ret)
474 return ret;
475 if (copy_to_user(up, &op, sizeof(op)))
476 return -EFAULT;
477 break;
478 }
479
480 default:
481 return -ENOIOCTLCMD;
482 }
483
484 return 0;
485}
486
487static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
488 bool perm, struct vc_data *vc)
489{
490 struct unimapdesc tmp;
491
492 if (copy_from_user(&tmp, user_ud, sizeof tmp))
493 return -EFAULT;
494 switch (cmd) {
495 case PIO_UNIMAP:
496 if (!perm)
497 return -EPERM;
498 return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
499 case GIO_UNIMAP:
500 if (!perm && fg_console != vc->vc_num)
501 return -EPERM;
502 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
503 tmp.entries);
504 }
505 return 0;
506}
507
508static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
509 bool perm)
510{
511 switch (cmd) {
512 case PIO_CMAP:
513 if (!perm)
514 return -EPERM;
515 return con_set_cmap(up);
516
517 case GIO_CMAP:
518 return con_get_cmap(up);
519
520 case PIO_SCRNMAP:
521 if (!perm)
522 return -EPERM;
523 return con_set_trans_old(up);
524
525 case GIO_SCRNMAP:
526 return con_get_trans_old(up);
527
528 case PIO_UNISCRNMAP:
529 if (!perm)
530 return -EPERM;
531 return con_set_trans_new(up);
532
533 case GIO_UNISCRNMAP:
534 return con_get_trans_new(up);
535
536 case PIO_UNIMAPCLR:
537 if (!perm)
538 return -EPERM;
539 con_clear_unimap(vc);
540 break;
541
542 case PIO_UNIMAP:
543 case GIO_UNIMAP:
544 return do_unimap_ioctl(cmd, up, perm, vc);
545
546 default:
547 return -ENOIOCTLCMD;
548 }
549
550 return 0;
551}
552
553static int vt_reldisp(struct vc_data *vc, unsigned int swtch)
554{
555 int newvt, ret;
556
557 if (vc->vt_mode.mode != VT_PROCESS)
558 return -EINVAL;
559
560
561 if (vc->vt_newvt < 0) {
562
563 return swtch == VT_ACKACQ ? 0 : -EINVAL;
564 }
565
566
567 if (swtch == 0) {
568
569 vc->vt_newvt = -1;
570 return 0;
571 }
572
573
574 newvt = vc->vt_newvt;
575 vc->vt_newvt = -1;
576 ret = vc_allocate(newvt);
577 if (ret)
578 return ret;
579
580
581
582
583
584 complete_change_console(vc_cons[newvt].d);
585
586 return 0;
587}
588
589static int vt_setactivate(struct vt_setactivate __user *sa)
590{
591 struct vt_setactivate vsa;
592 struct vc_data *nvc;
593 int ret;
594
595 if (copy_from_user(&vsa, sa, sizeof(vsa)))
596 return -EFAULT;
597 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
598 return -ENXIO;
599
600 vsa.console = array_index_nospec(vsa.console, MAX_NR_CONSOLES + 1);
601 vsa.console--;
602 console_lock();
603 ret = vc_allocate(vsa.console);
604 if (ret) {
605 console_unlock();
606 return ret;
607 }
608
609
610
611
612
613 nvc = vc_cons[vsa.console].d;
614 nvc->vt_mode = vsa.mode;
615 nvc->vt_mode.frsig = 0;
616 put_pid(nvc->vt_pid);
617 nvc->vt_pid = get_pid(task_pid(current));
618 console_unlock();
619
620
621
622 set_console(vsa.console);
623
624 return 0;
625}
626
627
628static int vt_disallocate(unsigned int vc_num)
629{
630 struct vc_data *vc = NULL;
631 int ret = 0;
632
633 console_lock();
634 if (vt_busy(vc_num))
635 ret = -EBUSY;
636 else if (vc_num)
637 vc = vc_deallocate(vc_num);
638 console_unlock();
639
640 if (vc && vc_num >= MIN_NR_CONSOLES)
641 tty_port_put(&vc->port);
642
643 return ret;
644}
645
646
647static void vt_disallocate_all(void)
648{
649 struct vc_data *vc[MAX_NR_CONSOLES];
650 int i;
651
652 console_lock();
653 for (i = 1; i < MAX_NR_CONSOLES; i++)
654 if (!vt_busy(i))
655 vc[i] = vc_deallocate(i);
656 else
657 vc[i] = NULL;
658 console_unlock();
659
660 for (i = 1; i < MAX_NR_CONSOLES; i++) {
661 if (vc[i] && i >= MIN_NR_CONSOLES)
662 tty_port_put(&vc[i]->port);
663 }
664}
665
666static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
667{
668 struct vt_consize v;
669 int i;
670
671 if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
672 return -EFAULT;
673
674
675 if (!v.v_vlin)
676 v.v_vlin = vc->vc_scan_lines;
677
678 if (v.v_clin) {
679 int rows = v.v_vlin / v.v_clin;
680 if (v.v_rows != rows) {
681 if (v.v_rows)
682 return -EINVAL;
683 v.v_rows = rows;
684 }
685 }
686
687 if (v.v_vcol && v.v_ccol) {
688 int cols = v.v_vcol / v.v_ccol;
689 if (v.v_cols != cols) {
690 if (v.v_cols)
691 return -EINVAL;
692 v.v_cols = cols;
693 }
694 }
695
696 if (v.v_clin > 32)
697 return -EINVAL;
698
699 for (i = 0; i < MAX_NR_CONSOLES; i++) {
700 struct vc_data *vcp;
701
702 if (!vc_cons[i].d)
703 continue;
704 console_lock();
705 vcp = vc_cons[i].d;
706 if (vcp) {
707 int ret;
708 int save_scan_lines = vcp->vc_scan_lines;
709 int save_cell_height = vcp->vc_cell_height;
710
711 if (v.v_vlin)
712 vcp->vc_scan_lines = v.v_vlin;
713 if (v.v_clin)
714 vcp->vc_cell_height = v.v_clin;
715 vcp->vc_resize_user = 1;
716 ret = vc_resize(vcp, v.v_cols, v.v_rows);
717 if (ret) {
718 vcp->vc_scan_lines = save_scan_lines;
719 vcp->vc_cell_height = save_cell_height;
720 console_unlock();
721 return ret;
722 }
723 }
724 console_unlock();
725 }
726
727 return 0;
728}
729
730
731
732
733
734int vt_ioctl(struct tty_struct *tty,
735 unsigned int cmd, unsigned long arg)
736{
737 struct vc_data *vc = tty->driver_data;
738 void __user *up = (void __user *)arg;
739 int i, perm;
740 int ret;
741
742
743
744
745
746 perm = 0;
747 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
748 perm = 1;
749
750 ret = vt_k_ioctl(tty, cmd, arg, perm);
751 if (ret != -ENOIOCTLCMD)
752 return ret;
753
754 ret = vt_io_ioctl(vc, cmd, up, perm);
755 if (ret != -ENOIOCTLCMD)
756 return ret;
757
758 switch (cmd) {
759 case TIOCLINUX:
760 return tioclinux(tty, arg);
761 case VT_SETMODE:
762 {
763 struct vt_mode tmp;
764
765 if (!perm)
766 return -EPERM;
767 if (copy_from_user(&tmp, up, sizeof(struct vt_mode)))
768 return -EFAULT;
769 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
770 return -EINVAL;
771
772 console_lock();
773 vc->vt_mode = tmp;
774
775 vc->vt_mode.frsig = 0;
776 put_pid(vc->vt_pid);
777 vc->vt_pid = get_pid(task_pid(current));
778
779 vc->vt_newvt = -1;
780 console_unlock();
781 break;
782 }
783
784 case VT_GETMODE:
785 {
786 struct vt_mode tmp;
787 int rc;
788
789 console_lock();
790 memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
791 console_unlock();
792
793 rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
794 if (rc)
795 return -EFAULT;
796 break;
797 }
798
799
800
801
802
803
804 case VT_GETSTATE:
805 {
806 struct vt_stat __user *vtstat = up;
807 unsigned short state, mask;
808
809 if (put_user(fg_console + 1, &vtstat->v_active))
810 return -EFAULT;
811
812 state = 1;
813 console_lock();
814 for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
815 ++i, mask <<= 1)
816 if (vt_in_use(i))
817 state |= mask;
818 console_unlock();
819 return put_user(state, &vtstat->v_state);
820 }
821
822
823
824
825 case VT_OPENQRY:
826 console_lock();
827 for (i = 0; i < MAX_NR_CONSOLES; ++i)
828 if (!vt_in_use(i))
829 break;
830 console_unlock();
831 i = i < MAX_NR_CONSOLES ? (i+1) : -1;
832 return put_user(i, (int __user *)arg);
833
834
835
836
837
838
839 case VT_ACTIVATE:
840 if (!perm)
841 return -EPERM;
842 if (arg == 0 || arg > MAX_NR_CONSOLES)
843 return -ENXIO;
844
845 arg--;
846 console_lock();
847 ret = vc_allocate(arg);
848 console_unlock();
849 if (ret)
850 return ret;
851 set_console(arg);
852 break;
853
854 case VT_SETACTIVATE:
855 if (!perm)
856 return -EPERM;
857
858 return vt_setactivate(up);
859
860
861
862
863 case VT_WAITACTIVE:
864 if (!perm)
865 return -EPERM;
866 if (arg == 0 || arg > MAX_NR_CONSOLES)
867 return -ENXIO;
868 return vt_waitactive(arg);
869
870
871
872
873
874
875
876
877
878
879
880 case VT_RELDISP:
881 if (!perm)
882 return -EPERM;
883
884 console_lock();
885 ret = vt_reldisp(vc, arg);
886 console_unlock();
887
888 return ret;
889
890
891
892
893
894 case VT_DISALLOCATE:
895 if (arg > MAX_NR_CONSOLES)
896 return -ENXIO;
897
898 if (arg == 0)
899 vt_disallocate_all();
900 else
901 return vt_disallocate(--arg);
902 break;
903
904 case VT_RESIZE:
905 {
906 struct vt_sizes __user *vtsizes = up;
907 struct vc_data *vc;
908 ushort ll,cc;
909
910 if (!perm)
911 return -EPERM;
912 if (get_user(ll, &vtsizes->v_rows) ||
913 get_user(cc, &vtsizes->v_cols))
914 return -EFAULT;
915
916 console_lock();
917 for (i = 0; i < MAX_NR_CONSOLES; i++) {
918 vc = vc_cons[i].d;
919
920 if (vc) {
921 vc->vc_resize_user = 1;
922
923 vc_resize(vc_cons[i].d, cc, ll);
924 }
925 }
926 console_unlock();
927 break;
928 }
929
930 case VT_RESIZEX:
931 if (!perm)
932 return -EPERM;
933
934 return vt_resizex(vc, up);
935
936 case VT_LOCKSWITCH:
937 if (!capable(CAP_SYS_TTY_CONFIG))
938 return -EPERM;
939 vt_dont_switch = true;
940 break;
941 case VT_UNLOCKSWITCH:
942 if (!capable(CAP_SYS_TTY_CONFIG))
943 return -EPERM;
944 vt_dont_switch = false;
945 break;
946 case VT_GETHIFONTMASK:
947 return put_user(vc->vc_hi_font_mask,
948 (unsigned short __user *)arg);
949 case VT_WAITEVENT:
950 return vt_event_wait_ioctl((struct vt_event __user *)arg);
951 default:
952 return -ENOIOCTLCMD;
953 }
954
955 return 0;
956}
957
958void reset_vc(struct vc_data *vc)
959{
960 vc->vc_mode = KD_TEXT;
961 vt_reset_unicode(vc->vc_num);
962 vc->vt_mode.mode = VT_AUTO;
963 vc->vt_mode.waitv = 0;
964 vc->vt_mode.relsig = 0;
965 vc->vt_mode.acqsig = 0;
966 vc->vt_mode.frsig = 0;
967 put_pid(vc->vt_pid);
968 vc->vt_pid = NULL;
969 vc->vt_newvt = -1;
970 reset_palette(vc);
971}
972
973void vc_SAK(struct work_struct *work)
974{
975 struct vc *vc_con =
976 container_of(work, struct vc, SAK_work);
977 struct vc_data *vc;
978 struct tty_struct *tty;
979
980 console_lock();
981 vc = vc_con->d;
982 if (vc) {
983
984 tty = vc->port.tty;
985
986
987
988
989 if (tty)
990 __do_SAK(tty);
991 reset_vc(vc);
992 }
993 console_unlock();
994}
995
996#ifdef CONFIG_COMPAT
997
998struct compat_console_font_op {
999 compat_uint_t op;
1000 compat_uint_t flags;
1001 compat_uint_t width, height;
1002 compat_uint_t charcount;
1003 compat_caddr_t data;
1004};
1005
1006static inline int
1007compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1008 int perm, struct console_font_op *op, struct vc_data *vc)
1009{
1010 int i;
1011
1012 if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
1013 return -EFAULT;
1014 if (!perm && op->op != KD_FONT_OP_GET)
1015 return -EPERM;
1016 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1017 i = con_font_op(vc, op);
1018 if (i)
1019 return i;
1020 ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
1021 if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
1022 return -EFAULT;
1023 return 0;
1024}
1025
1026struct compat_unimapdesc {
1027 unsigned short entry_ct;
1028 compat_caddr_t entries;
1029};
1030
1031static inline int
1032compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
1033 int perm, struct vc_data *vc)
1034{
1035 struct compat_unimapdesc tmp;
1036 struct unipair __user *tmp_entries;
1037
1038 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1039 return -EFAULT;
1040 tmp_entries = compat_ptr(tmp.entries);
1041 switch (cmd) {
1042 case PIO_UNIMAP:
1043 if (!perm)
1044 return -EPERM;
1045 return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
1046 case GIO_UNIMAP:
1047 if (!perm && fg_console != vc->vc_num)
1048 return -EPERM;
1049 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
1050 }
1051 return 0;
1052}
1053
1054long vt_compat_ioctl(struct tty_struct *tty,
1055 unsigned int cmd, unsigned long arg)
1056{
1057 struct vc_data *vc = tty->driver_data;
1058 struct console_font_op op;
1059 void __user *up = compat_ptr(arg);
1060 int perm;
1061
1062
1063
1064
1065
1066 perm = 0;
1067 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1068 perm = 1;
1069
1070 switch (cmd) {
1071
1072
1073
1074
1075 case KDFONTOP:
1076 return compat_kdfontop_ioctl(up, perm, &op, vc);
1077
1078 case PIO_UNIMAP:
1079 case GIO_UNIMAP:
1080 return compat_unimap_ioctl(cmd, up, perm, vc);
1081
1082
1083
1084
1085 case KIOCSOUND:
1086 case KDMKTONE:
1087#ifdef CONFIG_X86
1088 case KDADDIO:
1089 case KDDELIO:
1090#endif
1091 case KDSETMODE:
1092 case KDMAPDISP:
1093 case KDUNMAPDISP:
1094 case KDSKBMODE:
1095 case KDSKBMETA:
1096 case KDSKBLED:
1097 case KDSETLED:
1098 case KDSIGACCEPT:
1099 case VT_ACTIVATE:
1100 case VT_WAITACTIVE:
1101 case VT_RELDISP:
1102 case VT_DISALLOCATE:
1103 case VT_RESIZE:
1104 case VT_RESIZEX:
1105 return vt_ioctl(tty, cmd, arg);
1106
1107
1108
1109
1110
1111 default:
1112 return vt_ioctl(tty, cmd, (unsigned long)up);
1113 }
1114}
1115
1116
1117#endif
1118
1119
1120
1121
1122
1123
1124static void complete_change_console(struct vc_data *vc)
1125{
1126 unsigned char old_vc_mode;
1127 int old = fg_console;
1128
1129 last_console = fg_console;
1130
1131
1132
1133
1134
1135
1136 old_vc_mode = vc_cons[fg_console].d->vc_mode;
1137 switch_screen(vc);
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 if (old_vc_mode != vc->vc_mode) {
1150 if (vc->vc_mode == KD_TEXT)
1151 do_unblank_screen(1);
1152 else
1153 do_blank_screen(1);
1154 }
1155
1156
1157
1158
1159
1160
1161 if (vc->vt_mode.mode == VT_PROCESS) {
1162
1163
1164
1165
1166
1167 if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177 reset_vc(vc);
1178
1179 if (old_vc_mode != vc->vc_mode) {
1180 if (vc->vc_mode == KD_TEXT)
1181 do_unblank_screen(1);
1182 else
1183 do_blank_screen(1);
1184 }
1185 }
1186 }
1187
1188
1189
1190
1191 vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
1192 return;
1193}
1194
1195
1196
1197
1198void change_console(struct vc_data *new_vc)
1199{
1200 struct vc_data *vc;
1201
1202 if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
1203 return;
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 vc = vc_cons[fg_console].d;
1221 if (vc->vt_mode.mode == VT_PROCESS) {
1222
1223
1224
1225
1226
1227
1228
1229
1230 vc->vt_newvt = new_vc->vc_num;
1231 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1232
1233
1234
1235
1236
1237 return;
1238 }
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 reset_vc(vc);
1250
1251
1252
1253
1254 }
1255
1256
1257
1258
1259 if (vc->vc_mode == KD_GRAPHICS)
1260 return;
1261
1262 complete_change_console(new_vc);
1263}
1264
1265
1266
1267static int disable_vt_switch;
1268
1269int vt_move_to_console(unsigned int vt, int alloc)
1270{
1271 int prev;
1272
1273 console_lock();
1274
1275 if (disable_vt_switch) {
1276 console_unlock();
1277 return 0;
1278 }
1279 prev = fg_console;
1280
1281 if (alloc && vc_allocate(vt)) {
1282
1283
1284 console_unlock();
1285 return -ENOSPC;
1286 }
1287
1288 if (set_console(vt)) {
1289
1290
1291
1292
1293
1294 console_unlock();
1295 return -EIO;
1296 }
1297 console_unlock();
1298 if (vt_waitactive(vt + 1)) {
1299 pr_debug("Suspend: Can't switch VCs.");
1300 return -EINTR;
1301 }
1302 return prev;
1303}
1304
1305
1306
1307
1308
1309
1310
1311
1312void pm_set_vt_switch(int do_switch)
1313{
1314 console_lock();
1315 disable_vt_switch = !do_switch;
1316 console_unlock();
1317}
1318EXPORT_SYMBOL(pm_set_vt_switch);
1319