Ejemplo n.º 1
0
/**
 * vtpmx_ioc_new_dev - handler for the %VTPM_PROXY_IOC_NEW_DEV ioctl
 * @file:	/dev/vtpmx
 * @ioctl:	the ioctl number
 * @arg:	pointer to the struct vtpmx_proxy_new_dev
 *
 * Creates an anonymous file that is used by the process acting as a TPM to
 * communicate with the client processes. The function will also add a new TPM
 * device through which data is proxied to this TPM acting process. The caller
 * will be provided with a file descriptor to communicate with the clients and
 * major and minor numbers for the TPM device.
 */
static long vtpmx_ioc_new_dev(struct file *file, unsigned int ioctl,
			      unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct vtpm_proxy_new_dev __user *vtpm_new_dev_p;
	struct vtpm_proxy_new_dev vtpm_new_dev;
	struct file *vtpm_file;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	vtpm_new_dev_p = argp;

	if (copy_from_user(&vtpm_new_dev, vtpm_new_dev_p,
			   sizeof(vtpm_new_dev)))
		return -EFAULT;

	vtpm_file = vtpm_proxy_create_device(&vtpm_new_dev);
	if (IS_ERR(vtpm_file))
		return PTR_ERR(vtpm_file);

	if (copy_to_user(vtpm_new_dev_p, &vtpm_new_dev,
			 sizeof(vtpm_new_dev))) {
		put_unused_fd(vtpm_new_dev.fd);
		fput(vtpm_file);
		return -EFAULT;
	}

	fd_install(vtpm_new_dev.fd, vtpm_file);
	return 0;
}
Ejemplo n.º 2
0
/*
 * vtpmx_fops_ioctl: ioctl on /dev/vtpmx
 *
 * Return value:
 *      Returns 0 on success, a negative error code otherwise.
 */
static long vtpmx_fops_ioctl(struct file *f, unsigned int ioctl,
				   unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct vtpm_proxy_new_dev __user *vtpm_new_dev_p;
	struct vtpm_proxy_new_dev vtpm_new_dev;
	struct file *file;

	switch (ioctl) {
	case VTPM_PROXY_IOC_NEW_DEV:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		vtpm_new_dev_p = argp;
		if (copy_from_user(&vtpm_new_dev, vtpm_new_dev_p,
				   sizeof(vtpm_new_dev)))
			return -EFAULT;
		file = vtpm_proxy_create_device(&vtpm_new_dev);
		if (IS_ERR(file))
			return PTR_ERR(file);
		if (copy_to_user(vtpm_new_dev_p, &vtpm_new_dev,
				 sizeof(vtpm_new_dev))) {
			put_unused_fd(vtpm_new_dev.fd);
			fput(file);
			return -EFAULT;
		}

		fd_install(vtpm_new_dev.fd, file);
		return 0;

	default:
		return -ENOIOCTLCMD;
	}
}