Ejemplo n.º 1
0
static int compat_drm_addbufs(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	drm_buf_desc32_t __user *argp = (void __user *)arg;
	struct drm_buf_desc __user *buf;
	int err;
	unsigned long agp_start;

	buf = compat_alloc_user_space(sizeof(*buf));
	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
	    || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
		return -EFAULT;

	if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
	    || __get_user(agp_start, &argp->agp_start)
	    || __put_user(agp_start, &buf->agp_start))
		return -EFAULT;

	err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
	if (err)
		return err;

	if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
	    || __get_user(agp_start, &buf->agp_start)
	    || __put_user(agp_start, &argp->agp_start))
		return -EFAULT;

	return 0;
}
Ejemplo n.º 2
0
static int compat_drm_infobufs(struct file *file, unsigned int cmd,
                               unsigned long arg)
{
    drm_buf_info32_t req32;
    drm_buf_info32_t __user *argp = (void __user *)arg;
    drm_buf_desc32_t __user *to;
    drm_buf_info_t __user *request;
    drm_buf_desc_t __user *list;
    size_t nbytes;
    int i, err;
    int count, actual;

    if (copy_from_user(&req32, argp, sizeof(req32)))
        return -EFAULT;

    count = req32.count;
    to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
    if (count < 0)
        count = 0;
    if (count > 0
            && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
        return -EFAULT;

    nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t);
    request = compat_alloc_user_space(nbytes);
    if (!access_ok(VERIFY_WRITE, request, nbytes))
        return -EFAULT;
    list = (drm_buf_desc_t *) (request + 1);

    if (__put_user(count, &request->count)
            || __put_user(list, &request->list))
        return -EFAULT;

    err = drm_ioctl(file->f_dentry->d_inode, file,
                    DRM_IOCTL_INFO_BUFS, (unsigned long)request);
    if (err)
        return err;

    if (__get_user(actual, &request->count))
        return -EFAULT;
    if (count >= actual)
        for (i = 0; i < actual; ++i)
            if (__copy_in_user(&to[i], &list[i],
                               offsetof(drm_buf_desc_t, flags)))
                return -EFAULT;

    if (__put_user(actual, &argp->count))
        return -EFAULT;

    return 0;
}
Ejemplo n.º 3
0
static int do_netfilter_replace(int fd, int level, int optname,
				char __user *optval, int optlen)
{
	struct compat_ipt_replace __user *urepl;
	struct ipt_replace __user *repl_nat;
	char name[IPT_TABLE_MAXNAMELEN];
	u32 origsize, tmp32, num_counters;
	unsigned int repl_nat_size;
	int ret;
	int i;
	compat_uptr_t ucntrs;

	urepl = (struct compat_ipt_replace __user *)optval;
	if (get_user(origsize, &urepl->size))
		return -EFAULT;

	/* Hack: Causes ipchains to give correct error msg --RR */
	if (optlen != sizeof(*urepl) + origsize)
		return -ENOPROTOOPT;

	/* XXX Assumes that size of ipt_entry is the same both in
	 *     native and compat environments.
	 */
	repl_nat_size = sizeof(*repl_nat) + origsize;
	repl_nat = compat_alloc_user_space(repl_nat_size);

	ret = -EFAULT;
	if (put_user(origsize, &repl_nat->size))
		goto out;

	if (!access_ok(VERIFY_READ, urepl, optlen) ||
	    !access_ok(VERIFY_WRITE, repl_nat, optlen))
		goto out;

	if (__copy_from_user(name, urepl->name, sizeof(urepl->name)) ||
	    __copy_to_user(repl_nat->name, name, sizeof(repl_nat->name)))
		goto out;

	if (__get_user(tmp32, &urepl->valid_hooks) ||
	    __put_user(tmp32, &repl_nat->valid_hooks))
		goto out;

	if (__get_user(tmp32, &urepl->num_entries) ||
	    __put_user(tmp32, &repl_nat->num_entries))
		goto out;

	if (__get_user(num_counters, &urepl->num_counters) ||
	    __put_user(num_counters, &repl_nat->num_counters))
		goto out;

	if (__get_user(ucntrs, &urepl->counters) ||
	    __put_user(compat_ptr(ucntrs), &repl_nat->counters))
		goto out;

	if (__copy_in_user(&repl_nat->entries[0],
			   &urepl->entries[0],
			   origsize))
		goto out;

	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		if (__get_user(tmp32, &urepl->hook_entry[i]) ||
		    __put_user(tmp32, &repl_nat->hook_entry[i]) ||
		    __get_user(tmp32, &urepl->underflow[i]) ||
		    __put_user(tmp32, &repl_nat->underflow[i]))
			goto out;
	}

	/*
	 * Since struct ipt_counters just contains two u_int64_t members
	 * we can just do the access_ok check here and pass the (converted)
	 * pointer into the standard syscall.  We hope that the pointer is
	 * not misaligned ...
	 */
	if (!access_ok(VERIFY_WRITE, compat_ptr(ucntrs),
		       num_counters * sizeof(struct ipt_counters)))
		goto out;


	ret = sys_setsockopt(fd, level, optname,
			     (char __user *)repl_nat, repl_nat_size);

out:
	return ret;
}