Commit ebf1efbb authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman
Browse files

vt_ioctl: move vt_setactivate out of vt_ioctl

parent bfbbdfa4
Loading
Loading
Loading
Loading
+39 −35
Original line number Diff line number Diff line
@@ -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