Beispiel #1
0
/* I've named the args so it is easy to tell whose space the pointers are in. */
int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
		   struct sockaddr_storage *kern_address, int mode)
{
	int tot_len;

	if (kern_msg->msg_namelen) {
		if (mode == VERIFY_READ) {
			int err = move_addr_to_kernel(kern_msg->msg_name,
						      kern_msg->msg_namelen,
						      kern_address);
			if (err < 0)
				return err;
		}
		kern_msg->msg_name = kern_address;
	} else
		kern_msg->msg_name = NULL;

	tot_len = iov_from_user_compat_to_kern(kern_iov,
					  (struct compat_iovec __user *)kern_msg->msg_iov,
					  kern_msg->msg_iovlen);
	if (tot_len >= 0)
		kern_msg->msg_iov = kern_iov;

	return tot_len;
}
Beispiel #2
0
int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
{
	int size, err, ct;

	if (m->msg_namelen) {
		if (mode == VERIFY_READ) {
			err = move_addr_to_kernel(m->msg_name, m->msg_namelen,
						  address);
			if (err < 0)
				return err;
		}
		m->msg_name = address;
	} else {
		m->msg_name = NULL;
	}

	size = m->msg_iovlen * sizeof(struct iovec);
	if (copy_from_user(iov, m->msg_iov, size))
		return -EFAULT;

	m->msg_iov = iov;
	err = 0;

	for (ct = 0; ct < m->msg_iovlen; ct++) {
		size_t len = iov[ct].iov_len;

		if (len > INT_MAX - err) {
			len = INT_MAX - err;
			iov[ct].iov_len = len;
		}
		err += len;
	}

	return err;
}
Beispiel #3
0
int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode)
{
	int size, err, ct;
	
	if(m->msg_namelen)
	{
		if(mode==VERIFY_READ)
		{
			err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
			if(err<0)
				goto out;
		}
		
		m->msg_name = address;
	} else
		m->msg_name = NULL;

	err = -EFAULT;
	size = m->msg_iovlen * sizeof(struct iovec);
	if (copy_from_user(iov, m->msg_iov, size))
		goto out;
	m->msg_iov=iov;

	for (err = 0, ct = 0; ct < m->msg_iovlen; ct++)
		err += iov[ct].iov_len;
out:
	return err;
}
Beispiel #4
0
/* I've named the args so it is easy to tell whose space the pointers are in. */
int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
		   char *kern_address, int mode)
{
	int tot_len;

	if(kern_msg->msg_namelen) {
		if(mode==VERIFY_READ) {
			int err = move_addr_to_kernel(kern_msg->msg_name,
						      kern_msg->msg_namelen,
						      kern_address);
			if(err < 0)
				return err;
		}
		kern_msg->msg_name = kern_address;
	} else
		kern_msg->msg_name = NULL;

	if(kern_msg->msg_iovlen > UIO_FASTIOV) {
		kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
				   GFP_KERNEL);
		if(!kern_iov)
			return -ENOMEM;
	}

	tot_len = iov_from_user_compat_to_kern(kern_iov,
					  (struct compat_iovec __user *)kern_msg->msg_iov,
					  kern_msg->msg_iovlen);
	if(tot_len >= 0)
		kern_msg->msg_iov = kern_iov;
	else if(kern_msg->msg_iovlen > UIO_FASTIOV)
		kfree(kern_iov);

	return tot_len;
}
Beispiel #5
0
int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode)
{
	int size, err, ct;
	
	if(m->msg_namelen)
	{
		if(mode==VERIFY_READ)
		{
			err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
			if(err<0)
				goto out;
		}
		
		m->msg_name = address;
	} else
		m->msg_name = NULL;

	err = -EFAULT;
	size = m->msg_iovlen * sizeof(struct iovec);
	if (copy_from_user(iov, m->msg_iov, size))
		goto out;
	m->msg_iov=iov;

	for (err = 0, ct = 0; ct < m->msg_iovlen; ct++) {
		err += iov[ct].iov_len;
		/* Goal is not to verify user data, but to prevent returning
		   negative value, which is interpreted as errno.
		   Overflow is still possible, but it is harmless.
		 */
		if (err < 0)
			return -EMSGSIZE;
	}
out:
	return err;
}
Beispiel #6
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);
}
Beispiel #7
0
ssize_t 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;
	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(kmsg->msg_iovlen, &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 (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 (kmsg->msg_iovlen > UIO_MAXIOV)
		return -EMSGSIZE;

	err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE,
					   compat_ptr(uiov), kmsg->msg_iovlen,
					   UIO_FASTIOV, *iov, iov);
	if (err >= 0)
		kmsg->msg_iov = *iov;
	return err;
}
Beispiel #8
0
static int
efab_tcp_helper_bind_os_sock_rsop(ci_private_t* priv, void *arg)
{
  oo_tcp_bind_os_sock_t *op = arg;
  struct sockaddr_storage k_address_buf;
  int addrlen = op->addrlen;
  ci_uint16 port;
  int rc;

  if (priv->thr == NULL)
    return -EINVAL;
  rc = move_addr_to_kernel(CI_USER_PTR_GET(op->address), addrlen,
                           (struct sockaddr *)&k_address_buf);
  if( rc < 0 )
    return rc;
  rc = efab_tcp_helper_bind_os_sock(priv->thr, op->sock_id,
                                    (struct sockaddr *)&k_address_buf,
                                    addrlen, &port);
  if( rc < 0 )
    return rc;
  op->addrlen = port;
  return 0;
}