Commit 2e8039c6 authored by Michael Guralnik's avatar Michael Guralnik Committed by Jason Gunthorpe

IB/core: uverbs copy to struct or zero helper

Add a helper to zero fill fields before copying data to
UVERBS_ATTR_STRUCT.

As UVERBS_ATTR_STRUCT can be used as an extensible struct, we want to make
sure that if the user supplies us with a struct that has new fields that
we are not aware of, we return them zeroed to the user.

This helper should be used when using UVERBS_ATTR_STRUCT for an extendable
data structure and there is a need to make sure that extended members of
the struct, that the kernel doesn't handle, are returned zeroed to the
user. This is needed due to the fact that UVERBS_ATTR_STRUCT allows
non-zero values for members after 'last' member.
Signed-off-by: default avatarMichael Guralnik <michaelgur@mellanox.com>
Reviewed-by: default avatarMajd Dibbiny <majd@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent f55c3ec4
...@@ -751,3 +751,14 @@ int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, ...@@ -751,3 +751,14 @@ int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
return 0; return 0;
} }
EXPORT_SYMBOL(_uverbs_get_const); EXPORT_SYMBOL(_uverbs_get_const);
int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size)
{
const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
if (clear_user(u64_to_user_ptr(attr->ptr_attr.data),
attr->ptr_attr.len))
return -EFAULT;
return uverbs_copy_to(bundle, idx, from, size);
}
...@@ -871,6 +871,8 @@ static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle, ...@@ -871,6 +871,8 @@ static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle,
int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
size_t idx, s64 lower_bound, u64 upper_bound, size_t idx, s64 lower_bound, u64 upper_bound,
s64 *def_val); s64 *def_val);
int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size);
#else #else
static inline int static inline int
uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
...@@ -906,6 +908,12 @@ _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, ...@@ -906,6 +908,12 @@ _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
{ {
return -EINVAL; return -EINVAL;
} }
static inline int
uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size)
{
return -EINVAL;
}
#endif #endif
#define uverbs_get_const(_to, _attrs_bundle, _idx) \ #define uverbs_get_const(_to, _attrs_bundle, _idx) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment