diff options
Diffstat (limited to 'drivers/tty/vt/vt_ioctl.c')
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 978c33ad6619..e8bcfcdbedbb 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -633,6 +633,44 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up, return 0; } +static int vt_setactivate(struct vt_setactivate __user *sa) +{ + struct vt_setactivate vsa; + struct vc_data *nvc; + int ret; + + if (copy_from_user(&vsa, sa, sizeof(vsa))) + return -EFAULT; + if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) + 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(); + 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); + + return 0; +} + /* deallocate a single console, if possible (leave 0) */ static int vt_disallocate(unsigned int vc_num) { @@ -797,44 +835,10 @@ int vt_ioctl(struct tty_struct *tty, 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))) - return -EFAULT; - if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) - 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(); - 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; - } + return vt_setactivate(up); /* * wait until the specified VT has been activated |