From: Dave Airlie <airlied@redhat.com>
Date: Thu, 10 Aug 2023 18:50:20 +0000 (+1000)
Subject: nouveau/u_memcpya: use vmemdup_user
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e3885f71213437e7fa3e347d16b2bf59d03ae05d;p=linux.git

nouveau/u_memcpya: use vmemdup_user

I think there are limit checks in place for most things but the
new uAPI wants to not have them.

Add a limit check and use the vmemdup_user helper instead.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Danilo Krummrich <dakr@redhat.com>
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230810185020.231135-1-airlied@gmail.com
---

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 1fe17ff95f5ee..3666a7403e472 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 int nmemb, unsigned int 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>