From: Dave Airlie <airlied at redhat.com> I think there are limit checks in places for most things but the new api wants to not have them. Add a limit check and use the vmemdup_user helper instead. Signed-off-by: Dave Airlie <airlied at redhat.com> --- drivers/gpu/drm/nouveau/nouveau_drv.h | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 54063b094a69..8a7357688aff 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -189,21 +189,12 @@ u_free(void *addr) static inline void * u_memcpya(uint64_t user, unsigned nmemb, unsigned size) { - void *mem; - void __user *userptr = (void __force __user *)(uintptr_t)user; + void __user *userptr = u64_to_user_ptr(user); + size_t bytes; - size *= nmemb; - - mem = kvmalloc(size, GFP_KERNEL); - if (!mem) - return ERR_PTR(-ENOMEM); - - if (copy_from_user(mem, userptr, size)) { - u_free(mem); - return ERR_PTR(-EFAULT); - } - - return mem; + if (unlikely(check_mul_overflow(nmemb, size, &bytes))) + return NULL; + return vmemdup_user(userptr, bytes); } #include <nvif/object.h> -- 2.41.0
Danilo Krummrich
2023-Aug-10 20:46 UTC
[Nouveau] [PATCH] nouveau/u_memcpya: use vmemdup_user
On 8/10/23 20:50, Dave Airlie wrote:> From: Dave Airlie <airlied at redhat.com> > > I think there are limit checks in places for most things but the > new api wants to not have them. > > Add a limit check and use the vmemdup_user helper instead.Reviewed-by: Danilo Krummrich <dakr at redhat.com>> > Signed-off-by: Dave Airlie <airlied at redhat.com> > --- > drivers/gpu/drm/nouveau/nouveau_drv.h | 19 +++++-------------- > 1 file changed, 5 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h > index 54063b094a69..8a7357688aff 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_drv.h > +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h > @@ -189,21 +189,12 @@ u_free(void *addr) > static inline void * > u_memcpya(uint64_t user, unsigned nmemb, unsigned size) > { > - void *mem; > - void __user *userptr = (void __force __user *)(uintptr_t)user; > + void __user *userptr = u64_to_user_ptr(user); > + size_t bytes; > > - size *= nmemb; > - > - mem = kvmalloc(size, GFP_KERNEL); > - if (!mem) > - return ERR_PTR(-ENOMEM); > - > - if (copy_from_user(mem, userptr, size)) { > - u_free(mem); > - return ERR_PTR(-EFAULT); > - } > - > - return mem; > + if (unlikely(check_mul_overflow(nmemb, size, &bytes))) > + return NULL; > + return vmemdup_user(userptr, bytes); > } > > #include <nvif/object.h>