Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f36028c authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

IB/uverbs: Use u64_to_user_ptr() not a union



The union approach will get the endianness wrong sometimes if the kernel's
pointer size is 32 bits resulting in EFAULTs when trying to copy to/from
user.

Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 6c976c30
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -238,14 +238,14 @@ static void create_udata(struct uverbs_attr_bundle *ctx,
		if (uverbs_attr_ptr_is_inline(uhw_in))
			udata->inbuf = &uhw_in->uattr->data;
		else
			udata->inbuf = uhw_in->ptr_attr.ptr;
			udata->inbuf = u64_to_user_ptr(uhw_in->ptr_attr.data);
	} else {
		udata->inbuf = NULL;
		udata->inlen = 0;
	}

	if (!IS_ERR(uhw_out)) {
		udata->outbuf = uhw_out->ptr_attr.ptr;
		udata->outbuf = u64_to_user_ptr(uhw_out->ptr_attr.data);
		udata->outlen = uhw_out->ptr_attr.len;
	} else {
		udata->outbuf = NULL;
+4 −6
Original line number Diff line number Diff line
@@ -276,10 +276,7 @@ struct uverbs_object_tree_def {
 */

struct uverbs_ptr_attr {
	union {
	u64		data;
		void	__user *ptr;
	};
	u16		len;
	/* Combination of bits from enum UVERBS_ATTR_F_XXXX */
	u16		flags;
@@ -361,7 +358,7 @@ static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
		return PTR_ERR(attr);

	min_size = min_t(size_t, attr->ptr_attr.len, size);
	if (copy_to_user(attr->ptr_attr.ptr, from, min_size))
	if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size))
		return -EFAULT;

	flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
@@ -396,7 +393,8 @@ static inline int _uverbs_copy_from(void *to,

	if (uverbs_attr_ptr_is_inline(attr))
		memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
	else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len))
	else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
				attr->ptr_attr.len))
		return -EFAULT;

	return 0;