diff options
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 318 |
1 files changed, 133 insertions, 185 deletions
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index daf61c28ba76..87fe088c3eb4 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -357,7 +357,7 @@ int vt_ioctl(struct tty_struct *tty, unsigned int uival; void __user *up = (void __user *)arg; int i, perm; - int ret = 0; + int ret; /* * To have permissions to do most of the vt ioctls, we either have @@ -369,8 +369,7 @@ int vt_ioctl(struct tty_struct *tty, switch (cmd) { case TIOCLINUX: - ret = tioclinux(tty, arg); - break; + return tioclinux(tty, arg); case KIOCSOUND: if (!perm) return -EPERM; @@ -408,8 +407,7 @@ int vt_ioctl(struct tty_struct *tty, * this is naïve. */ ucval = KB_101; - ret = put_user(ucval, (char __user *)arg); - break; + return put_user(ucval, (char __user *)arg); /* * These cannot be implemented on any machine that implements @@ -426,18 +424,15 @@ int vt_ioctl(struct tty_struct *tty, * * These are locked internally via sys_ioperm */ - if (arg < GPFIRST || arg > GPLAST) { - ret = -EINVAL; - break; - } - ret = ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; - break; + if (arg < GPFIRST || arg > GPLAST) + return -EINVAL; + + return ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; case KDENABIO: case KDDISABIO: - ret = ksys_ioperm(GPFIRST, GPNUM, + return ksys_ioperm(GPFIRST, GPNUM, (cmd == KDENABIO)) ? -ENXIO : 0; - break; #endif /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */ @@ -449,15 +444,14 @@ int vt_ioctl(struct tty_struct *tty, if (!capable(CAP_SYS_TTY_CONFIG)) return -EPERM; - if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) + return -EFAULT; + ret = kbd_rate(&kbrep); if (ret) - break; + return ret; if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat))) - ret = -EFAULT; + return -EFAULT; break; } @@ -481,8 +475,7 @@ int vt_ioctl(struct tty_struct *tty, case KD_TEXT: break; default: - ret = -EINVAL; - goto out; + return -EINVAL; } /* FIXME: this needs the console lock extending */ if (vc->vc_mode == (unsigned char) arg) @@ -511,51 +504,45 @@ int vt_ioctl(struct tty_struct *tty, * these work like a combination of mmap and KDENABIO. * this could be easily finished. */ - ret = -EINVAL; - break; + return -EINVAL; case KDSKBMODE: if (!perm) return -EPERM; ret = vt_do_kdskbmode(console, arg); - if (ret == 0) - tty_ldisc_flush(tty); + if (ret) + return ret; + tty_ldisc_flush(tty); break; case KDGKBMODE: uival = vt_do_kdgkbmode(console); - ret = put_user(uival, (int __user *)arg); - break; + return put_user(uival, (int __user *)arg); /* this could be folded into KDSKBMODE, but for compatibility reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ case KDSKBMETA: - ret = vt_do_kdskbmeta(console, arg); - break; + return vt_do_kdskbmeta(console, arg); case KDGKBMETA: /* FIXME: should review whether this is worth locking */ uival = vt_do_kdgkbmeta(console); setint: - ret = put_user(uival, (int __user *)arg); - break; + return put_user(uival, (int __user *)arg); case KDGETKEYCODE: case KDSETKEYCODE: if(!capable(CAP_SYS_TTY_CONFIG)) perm = 0; - ret = vt_do_kbkeycode_ioctl(cmd, up, perm); - break; + return vt_do_kbkeycode_ioctl(cmd, up, perm); case KDGKBENT: case KDSKBENT: - ret = vt_do_kdsk_ioctl(cmd, up, perm, console); - break; + return vt_do_kdsk_ioctl(cmd, up, perm, console); case KDGKBSENT: case KDSKBSENT: - ret = vt_do_kdgkb_ioctl(cmd, up, perm); - break; + return vt_do_kdgkb_ioctl(cmd, up, perm); /* Diacritical processing. Handled in keyboard.c as it has to operate on the keyboard locks and structures */ @@ -563,8 +550,7 @@ int vt_ioctl(struct tty_struct *tty, case KDGKBDIACRUC: case KDSKBDIACR: case KDSKBDIACRUC: - ret = vt_do_diacrit(cmd, up, perm); - break; + return vt_do_diacrit(cmd, up, perm); /* the ioctls below read/set the flags usually shown in the leds */ /* don't use them - they will go away without warning */ @@ -572,8 +558,7 @@ int vt_ioctl(struct tty_struct *tty, case KDSKBLED: case KDGETLED: case KDSETLED: - ret = vt_do_kdskled(console, cmd, arg, perm); - break; + return vt_do_kdskled(console, cmd, arg, perm); /* * A process can indicate its willingness to accept signals @@ -583,20 +568,17 @@ int vt_ioctl(struct tty_struct *tty, * See also the kbrequest field of inittab(5). */ case KDSIGACCEPT: - { if (!perm || !capable(CAP_KILL)) return -EPERM; if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) - ret = -EINVAL; - else { - spin_lock_irq(&vt_spawn_con.lock); - put_pid(vt_spawn_con.pid); - vt_spawn_con.pid = get_pid(task_pid(current)); - vt_spawn_con.sig = arg; - spin_unlock_irq(&vt_spawn_con.lock); - } + return -EINVAL; + + spin_lock_irq(&vt_spawn_con.lock); + put_pid(vt_spawn_con.pid); + vt_spawn_con.pid = get_pid(task_pid(current)); + vt_spawn_con.sig = arg; + spin_unlock_irq(&vt_spawn_con.lock); break; - } case VT_SETMODE: { @@ -604,14 +586,11 @@ int vt_ioctl(struct tty_struct *tty, if (!perm) return -EPERM; - if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { - ret = -EFAULT; - goto out; - } - if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { - ret = -EINVAL; - goto out; - } + if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) + return -EFAULT; + if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) + return -EINVAL; + console_lock(); vc->vt_mode = tmp; /* the frsig is ignored, so we set it to 0 */ @@ -635,7 +614,7 @@ int vt_ioctl(struct tty_struct *tty, rc = copy_to_user(up, &tmp, sizeof(struct vt_mode)); if (rc) - ret = -EFAULT; + return -EFAULT; break; } @@ -650,18 +629,16 @@ int vt_ioctl(struct tty_struct *tty, unsigned short state, mask; if (put_user(fg_console + 1, &vtstat->v_active)) - ret = -EFAULT; - else { - state = 1; /* /dev/tty0 is always open */ - console_lock(); /* required by vt_in_use() */ - for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; - ++i, mask <<= 1) - if (vt_in_use(i)) - state |= mask; - console_unlock(); - ret = put_user(state, &vtstat->v_state); - } - break; + return -EFAULT; + + state = 1; /* /dev/tty0 is always open */ + console_lock(); /* required by vt_in_use() */ + for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; + ++i, mask <<= 1) + if (vt_in_use(i)) + state |= mask; + console_unlock(); + return put_user(state, &vtstat->v_state); } /* @@ -685,56 +662,54 @@ int vt_ioctl(struct tty_struct *tty, if (!perm) return -EPERM; if (arg == 0 || arg > MAX_NR_CONSOLES) - ret = -ENXIO; - else { - arg--; - console_lock(); - ret = vc_allocate(arg); - console_unlock(); - if (ret) - break; - set_console(arg); - } + return -ENXIO; + + arg--; + console_lock(); + ret = vc_allocate(arg); + console_unlock(); + if (ret) + return ret; + set_console(arg); break; case VT_SETACTIVATE: { struct vt_setactivate vsa; + struct vc_data *nvc; if (!perm) return -EPERM; if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, - sizeof(struct vt_setactivate))) { - ret = -EFAULT; - goto out; - } + sizeof(struct vt_setactivate))) + return -EFAULT; if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) - ret = -ENXIO; - else { - vsa.console = array_index_nospec(vsa.console, - MAX_NR_CONSOLES + 1); - vsa.console--; - console_lock(); - ret = vc_allocate(vsa.console); - if (ret == 0) { - struct vc_data *nvc; - /* This is safe providing we don't drop the - console sem between vc_allocate and - finishing referencing nvc */ - nvc = vc_cons[vsa.console].d; - nvc->vt_mode = vsa.mode; - nvc->vt_mode.frsig = 0; - put_pid(nvc->vt_pid); - nvc->vt_pid = get_pid(task_pid(current)); - } + return -ENXIO; + + vsa.console = array_index_nospec(vsa.console, + MAX_NR_CONSOLES + 1); + vsa.console--; + console_lock(); + ret = vc_allocate(vsa.console); + if (ret) { console_unlock(); - if (ret) - break; - /* Commence switch and lock */ - /* Review set_console locks */ - set_console(vsa.console); + return ret; } + + /* This is safe providing we don't drop the + console sem between vc_allocate and + finishing referencing nvc */ + nvc = vc_cons[vsa.console].d; + nvc->vt_mode = vsa.mode; + nvc->vt_mode.frsig = 0; + put_pid(nvc->vt_pid); + nvc->vt_pid = get_pid(task_pid(current)); + console_unlock(); + + /* Commence switch and lock */ + /* Review set_console locks */ + set_console(vsa.console); break; } @@ -745,10 +720,8 @@ int vt_ioctl(struct tty_struct *tty, if (!perm) return -EPERM; if (arg == 0 || arg > MAX_NR_CONSOLES) - ret = -ENXIO; - else - ret = vt_waitactive(arg); - break; + return -ENXIO; + return vt_waitactive(arg); /* * If a vt is under process control, the kernel will not switch to it @@ -767,8 +740,7 @@ int vt_ioctl(struct tty_struct *tty, console_lock(); if (vc->vt_mode.mode != VT_PROCESS) { console_unlock(); - ret = -EINVAL; - break; + return -EINVAL; } /* * Switching-from response @@ -792,7 +764,7 @@ int vt_ioctl(struct tty_struct *tty, ret = vc_allocate(newvt); if (ret) { console_unlock(); - break; + return ret; } /* * When we actually do the console switch, @@ -808,8 +780,10 @@ int vt_ioctl(struct tty_struct *tty, /* * If it's just an ACK, ignore it */ - if (arg != VT_ACKACQ) - ret = -EINVAL; + if (arg != VT_ACKACQ) { + console_unlock(); + return -EINVAL; + } } console_unlock(); break; @@ -818,40 +792,38 @@ int vt_ioctl(struct tty_struct *tty, * Disallocate memory associated to VT (but leave VT1) */ case VT_DISALLOCATE: - if (arg > MAX_NR_CONSOLES) { - ret = -ENXIO; - break; - } + if (arg > MAX_NR_CONSOLES) + return -ENXIO; + if (arg == 0) vt_disallocate_all(); else - ret = vt_disallocate(--arg); + return vt_disallocate(--arg); break; case VT_RESIZE: { struct vt_sizes __user *vtsizes = up; struct vc_data *vc; - ushort ll,cc; + if (!perm) return -EPERM; if (get_user(ll, &vtsizes->v_rows) || get_user(cc, &vtsizes->v_cols)) - ret = -EFAULT; - else { - console_lock(); - for (i = 0; i < MAX_NR_CONSOLES; i++) { - vc = vc_cons[i].d; + return -EFAULT; - if (vc) { - vc->vc_resize_user = 1; - /* FIXME: review v tty lock */ - vc_resize(vc_cons[i].d, cc, ll); - } + console_lock(); + for (i = 0; i < MAX_NR_CONSOLES; i++) { + vc = vc_cons[i].d; + + if (vc) { + vc->vc_resize_user = 1; + /* FIXME: review v tty lock */ + vc_resize(vc_cons[i].d, cc, ll); } - console_unlock(); } + console_unlock(); break; } @@ -905,7 +877,7 @@ int vt_ioctl(struct tty_struct *tty, break; } - case PIO_FONT: { + case PIO_FONT: if (!perm) return -EPERM; op.op = KD_FONT_OP_SET; @@ -914,98 +886,77 @@ int vt_ioctl(struct tty_struct *tty, op.height = 0; op.charcount = 256; op.data = up; - ret = con_font_op(vc_cons[fg_console].d, &op); - break; - } + return con_font_op(vc_cons[fg_console].d, &op); - case GIO_FONT: { + case GIO_FONT: op.op = KD_FONT_OP_GET; op.flags = KD_FONT_FLAG_OLD; op.width = 8; op.height = 32; op.charcount = 256; op.data = up; - ret = con_font_op(vc_cons[fg_console].d, &op); - break; - } + return con_font_op(vc_cons[fg_console].d, &op); case PIO_CMAP: if (!perm) - ret = -EPERM; - else - ret = con_set_cmap(up); - break; + return -EPERM; + return con_set_cmap(up); case GIO_CMAP: - ret = con_get_cmap(up); - break; + return con_get_cmap(up); case PIO_FONTX: case GIO_FONTX: - ret = do_fontx_ioctl(cmd, up, perm, &op); - break; + return do_fontx_ioctl(cmd, up, perm, &op); case PIO_FONTRESET: - { if (!perm) return -EPERM; #ifdef BROKEN_GRAPHICS_PROGRAMS /* With BROKEN_GRAPHICS_PROGRAMS defined, the default font is not saved. */ - ret = -ENOSYS; - break; + return -ENOSYS; #else - { op.op = KD_FONT_OP_SET_DEFAULT; op.data = NULL; ret = con_font_op(vc_cons[fg_console].d, &op); if (ret) - break; + return ret; console_lock(); con_set_default_unimap(vc_cons[fg_console].d); console_unlock(); break; - } #endif - } case KDFONTOP: { - if (copy_from_user(&op, up, sizeof(op))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&op, up, sizeof(op))) + return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) return -EPERM; ret = con_font_op(vc, &op); if (ret) - break; + return ret; if (copy_to_user(up, &op, sizeof(op))) - ret = -EFAULT; + return -EFAULT; break; } case PIO_SCRNMAP: if (!perm) - ret = -EPERM; - else - ret = con_set_trans_old(up); - break; + return -EPERM; + return con_set_trans_old(up); case GIO_SCRNMAP: - ret = con_get_trans_old(up); - break; + return con_get_trans_old(up); case PIO_UNISCRNMAP: if (!perm) - ret = -EPERM; - else - ret = con_set_trans_new(up); - break; + return -EPERM; + return con_set_trans_new(up); case GIO_UNISCRNMAP: - ret = con_get_trans_new(up); - break; + return con_get_trans_new(up); case PIO_UNIMAPCLR: if (!perm) @@ -1015,8 +966,7 @@ int vt_ioctl(struct tty_struct *tty, case PIO_UNIMAP: case GIO_UNIMAP: - ret = do_unimap_ioctl(cmd, up, perm, vc); - break; + return do_unimap_ioctl(cmd, up, perm, vc); case VT_LOCKSWITCH: if (!capable(CAP_SYS_TTY_CONFIG)) @@ -1029,17 +979,15 @@ int vt_ioctl(struct tty_struct *tty, vt_dont_switch = false; break; case VT_GETHIFONTMASK: - ret = put_user(vc->vc_hi_font_mask, + return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg); - break; case VT_WAITEVENT: - ret = vt_event_wait_ioctl((struct vt_event __user *)arg); - break; + return vt_event_wait_ioctl((struct vt_event __user *)arg); default: - ret = -ENOIOCTLCMD; + return -ENOIOCTLCMD; } -out: - return ret; + + return 0; } void reset_vc(struct vc_data *vc) |