@@ -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
It's too long to be inlined. Signed-off-by: Jiri Slaby <jslaby@suse.cz> --- drivers/tty/vt/vt_ioctl.c | 74 +++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 35 deletions(-)