コード例 #1
0
ファイル: read_write.c プロジェクト: vishalbhoj/linux
static ssize_t compat_do_readv_writev(int type, struct file *file,
			       const struct compat_iovec __user *uvector,
			       unsigned long nr_segs, loff_t *pos)
{
	compat_ssize_t tot_len;
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	struct iov_iter iter;
	ssize_t ret;
	io_fn_t fn;
	iov_fn_t fnv;
	iter_fn_t iter_fn;

	ret = compat_import_iovec(type, uvector, nr_segs,
				  UIO_FASTIOV, &iov, &iter);
	if (ret < 0)
		return ret;

	tot_len = iov_iter_count(&iter);
	if (!tot_len)
		goto out;
	ret = rw_verify_area(type, file, pos, tot_len);
	if (ret < 0)
		goto out;

	fnv = NULL;
	if (type == READ) {
		fn = file->f_op->read;
		fnv = file->f_op->aio_read;
		iter_fn = file->f_op->read_iter;
	} else {
		fn = (io_fn_t)file->f_op->write;
		fnv = file->f_op->aio_write;
		iter_fn = file->f_op->write_iter;
		file_start_write(file);
	}

	if (iter_fn)
		ret = do_iter_readv_writev(file, &iter, pos, iter_fn);
	else if (fnv)
		ret = do_sync_readv_writev(file, &iter, pos, fnv);
	else
		ret = do_loop_readv_writev(file, &iter, pos, fn);

	if (type != READ)
		file_end_write(file);

out:
	kfree(iov);
	if ((ret + (type == READ)) > 0) {
		if (type == READ)
			fsnotify_access(file);
		else
			fsnotify_modify(file);
	}
	return ret;
}
コード例 #2
0
int get_compat_msghdr(struct msghdr *kmsg,
                      struct compat_msghdr __user *umsg,
                      struct sockaddr __user **save_addr,
                      struct iovec **iov)
{
    compat_uptr_t uaddr, uiov, tmp3;
    compat_size_t nr_segs;
    ssize_t err;

    if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
            __get_user(uaddr, &umsg->msg_name) ||
            __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
            __get_user(uiov, &umsg->msg_iov) ||
            __get_user(nr_segs, &umsg->msg_iovlen) ||
            __get_user(tmp3, &umsg->msg_control) ||
            __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
            __get_user(kmsg->msg_flags, &umsg->msg_flags))
        return -EFAULT;

    if (!uaddr)
        kmsg->msg_namelen = 0;

    if (kmsg->msg_namelen < 0)
        return -EINVAL;

    if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
        kmsg->msg_namelen = sizeof(struct sockaddr_storage);
    kmsg->msg_control = compat_ptr(tmp3);

    if (save_addr)
        *save_addr = compat_ptr(uaddr);

    if (uaddr && kmsg->msg_namelen) {
        if (!save_addr) {
            err = move_addr_to_kernel(compat_ptr(uaddr),
                                      kmsg->msg_namelen,
                                      kmsg->msg_name);
            if (err < 0)
                return err;
        }
    } else {
        kmsg->msg_name = NULL;
        kmsg->msg_namelen = 0;
    }

    if (nr_segs > UIO_MAXIOV)
        return -EMSGSIZE;

    kmsg->msg_iocb = NULL;

    return compat_import_iovec(save_addr ? READ : WRITE,
                               compat_ptr(uiov), nr_segs,
                               UIO_FASTIOV, iov, &kmsg->msg_iter);
}
コード例 #3
0
ファイル: read_write.c プロジェクト: Anjali05/linux
static size_t compat_readv(struct file *file,
			   const struct compat_iovec __user *vec,
			   unsigned long vlen, loff_t *pos, rwf_t flags)
{
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	struct iov_iter iter;
	ssize_t ret;

	ret = compat_import_iovec(READ, vec, vlen, UIO_FASTIOV, &iov, &iter);
	if (ret >= 0) {
		ret = do_iter_read(file, &iter, pos, flags);
		kfree(iov);
	}
	if (ret > 0)
		add_rchar(current, ret);
	inc_syscr(current);
	return ret;
}
コード例 #4
0
static ssize_t
compat_process_vm_rw(compat_pid_t pid,
		     const struct compat_iovec __user *lvec,
		     unsigned long liovcnt,
		     const struct compat_iovec __user *rvec,
		     unsigned long riovcnt,
		     unsigned long flags, int vm_write)
{
	struct iovec iovstack_l[UIO_FASTIOV];
	struct iovec iovstack_r[UIO_FASTIOV];
	struct iovec *iov_l = iovstack_l;
	struct iovec *iov_r = iovstack_r;
	struct iov_iter iter;
	ssize_t rc = -EFAULT;
	int dir = vm_write ? WRITE : READ;

	if (flags != 0)
		return -EINVAL;

	rc = compat_import_iovec(dir, lvec, liovcnt, UIO_FASTIOV, &iov_l, &iter);
	if (rc < 0)
		return rc;
	if (!iov_iter_count(&iter))
		goto free_iovecs;
	rc = compat_rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt,
					  UIO_FASTIOV, iovstack_r,
					  &iov_r);
	if (rc <= 0)
		goto free_iovecs;

	rc = process_vm_rw_core(pid, &iter, iov_r, riovcnt, flags, vm_write);

free_iovecs:
	if (iov_r != iovstack_r)
		kfree(iov_r);
	kfree(iov_l);
	return rc;
}