* [PATCH v3 1/5] string.h: add array-wrappers for (v)memdup_user()
2023-09-20 12:36 [PATCH v3 0/5] Introduce new wrappers to copy user-arrays Philipp Stanner
@ 2023-09-20 12:36 ` Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 2/5] kernel: kexec: copy user-array safely Philipp Stanner
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Philipp Stanner @ 2023-09-20 12:36 UTC (permalink / raw)
To: Kees Cook, Andy Shevchenko, Eric Biederman, Christian Brauner,
David Disseldorp, Luis Chamberlain, Siddh Raman Pant, Nick Alcock,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Zack Rusin
Cc: VMware Graphics Reviewers, dri-devel, linux-kernel, kexec,
linux-hardening, Philipp Stanner, David Airlie, Andy Shevchenko
Currently, user array duplications are sometimes done without an
overflow check. Sometimes the checks are done manually; sometimes the
array size is calculated with array_size() and sometimes by calculating
n * size directly in code.
Introduce wrappers for arrays for memdup_user() and vmemdup_user() to
provide a standardized and safe way for duplicating user arrays.
This is both for new code as well as replacing usage of (v)memdup_user()
in existing code that uses, e.g., n * size to calculate array sizes.
Suggested-by: David Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
include/linux/string.h | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h
index dbfc66400050..debf4ef1098f 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -5,7 +5,9 @@
#include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */
#include <linux/stddef.h> /* for NULL */
+#include <linux/err.h> /* for ERR_PTR() */
#include <linux/errno.h> /* for E2BIG */
+#include <linux/overflow.h> /* for check_mul_overflow() */
#include <linux/stdarg.h>
#include <uapi/linux/string.h>
@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t);
extern void *vmemdup_user(const void __user *, size_t);
extern void *memdup_user_nul(const void __user *, size_t);
+/**
+ * memdup_array_user - duplicate array from user space
+ * @src: source address in user space
+ * @n: number of array members to copy
+ * @size: size of one array member
+ *
+ * Return: an ERR_PTR() on failure. Result is physically
+ * contiguous, to be freed by kfree().
+ */
+static inline void *memdup_array_user(const void __user *src, size_t n, size_t size)
+{
+ size_t nbytes;
+
+ if (check_mul_overflow(n, size, &nbytes))
+ return ERR_PTR(-EOVERFLOW);
+
+ return memdup_user(src, nbytes);
+}
+
+/**
+ * vmemdup_array_user - duplicate array from user space
+ * @src: source address in user space
+ * @n: number of array members to copy
+ * @size: size of one array member
+ *
+ * Return: an ERR_PTR() on failure. Result may be not
+ * physically contiguous. Use kvfree() to free.
+ */
+static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size)
+{
+ size_t nbytes;
+
+ if (check_mul_overflow(n, size, &nbytes))
+ return ERR_PTR(-EOVERFLOW);
+
+ return vmemdup_user(src, nbytes);
+}
+
/*
* Include machine specific inline routines
*/
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 2/5] kernel: kexec: copy user-array safely
2023-09-20 12:36 [PATCH v3 0/5] Introduce new wrappers to copy user-arrays Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 1/5] string.h: add array-wrappers for (v)memdup_user() Philipp Stanner
@ 2023-09-20 12:36 ` Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 3/5] kernel: watch_queue: " Philipp Stanner
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Philipp Stanner @ 2023-09-20 12:36 UTC (permalink / raw)
To: Kees Cook, Andy Shevchenko, Eric Biederman, Christian Brauner,
David Disseldorp, Luis Chamberlain, Siddh Raman Pant, Nick Alcock,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Zack Rusin
Cc: VMware Graphics Reviewers, dri-devel, linux-kernel, kexec,
linux-hardening, Philipp Stanner, David Airlie, Baoquan He
Currently, there is no overflow-check with memdup_user().
Use the new function memdup_array_user() instead of memdup_user() for
duplicating the user-space array safely.
Suggested-by: David Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Acked-by: Baoquan He <bhe@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
kernel/kexec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 107f355eac10..8f35a5a42af8 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -247,7 +247,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
return -EINVAL;
- ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0]));
+ ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0]));
if (IS_ERR(ksegments))
return PTR_ERR(ksegments);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 3/5] kernel: watch_queue: copy user-array safely
2023-09-20 12:36 [PATCH v3 0/5] Introduce new wrappers to copy user-arrays Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 1/5] string.h: add array-wrappers for (v)memdup_user() Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 2/5] kernel: kexec: copy user-array safely Philipp Stanner
@ 2023-09-20 12:36 ` Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 4/5] drm_lease.c: " Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 5/5] drm: vmgfx_surface.c: " Philipp Stanner
4 siblings, 0 replies; 6+ messages in thread
From: Philipp Stanner @ 2023-09-20 12:36 UTC (permalink / raw)
To: Kees Cook, Andy Shevchenko, Eric Biederman, Christian Brauner,
David Disseldorp, Luis Chamberlain, Siddh Raman Pant, Nick Alcock,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Zack Rusin
Cc: VMware Graphics Reviewers, dri-devel, linux-kernel, kexec,
linux-hardening, Philipp Stanner, David Airlie
Currently, there is no overflow-check with memdup_user().
Use the new function memdup_array_user() instead of memdup_user() for
duplicating the user-space array safely.
Suggested-by: David Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
kernel/watch_queue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index d0b6b390ee42..778b4056700f 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -331,7 +331,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe,
filter.__reserved != 0)
return -EINVAL;
- tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf));
+ tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf));
if (IS_ERR(tf))
return PTR_ERR(tf);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 4/5] drm_lease.c: copy user-array safely
2023-09-20 12:36 [PATCH v3 0/5] Introduce new wrappers to copy user-arrays Philipp Stanner
` (2 preceding siblings ...)
2023-09-20 12:36 ` [PATCH v3 3/5] kernel: watch_queue: " Philipp Stanner
@ 2023-09-20 12:36 ` Philipp Stanner
2023-09-20 12:36 ` [PATCH v3 5/5] drm: vmgfx_surface.c: " Philipp Stanner
4 siblings, 0 replies; 6+ messages in thread
From: Philipp Stanner @ 2023-09-20 12:36 UTC (permalink / raw)
To: Kees Cook, Andy Shevchenko, Eric Biederman, Christian Brauner,
David Disseldorp, Luis Chamberlain, Siddh Raman Pant, Nick Alcock,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Zack Rusin
Cc: VMware Graphics Reviewers, dri-devel, linux-kernel, kexec,
linux-hardening, Philipp Stanner, David Airlie
Currently, there is no overflow-check with memdup_user().
Use the new function memdup_array_user() instead of memdup_user() for
duplicating the user-space array safely.
Suggested-by: David Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
drivers/gpu/drm/drm_lease.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 150fe1555068..94375c6a5425 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -510,8 +510,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
/* Handle leased objects, if any */
idr_init(&leases);
if (object_count != 0) {
- object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
- array_size(object_count, sizeof(__u32)));
+ object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids),
+ object_count, sizeof(__u32));
if (IS_ERR(object_ids)) {
ret = PTR_ERR(object_ids);
idr_destroy(&leases);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v3 5/5] drm: vmgfx_surface.c: copy user-array safely
2023-09-20 12:36 [PATCH v3 0/5] Introduce new wrappers to copy user-arrays Philipp Stanner
` (3 preceding siblings ...)
2023-09-20 12:36 ` [PATCH v3 4/5] drm_lease.c: " Philipp Stanner
@ 2023-09-20 12:36 ` Philipp Stanner
4 siblings, 0 replies; 6+ messages in thread
From: Philipp Stanner @ 2023-09-20 12:36 UTC (permalink / raw)
To: Kees Cook, Andy Shevchenko, Eric Biederman, Christian Brauner,
David Disseldorp, Luis Chamberlain, Siddh Raman Pant, Nick Alcock,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Zack Rusin
Cc: VMware Graphics Reviewers, dri-devel, linux-kernel, kexec,
linux-hardening, Philipp Stanner, David Airlie
Currently, there is no overflow-check with memdup_user().
Use the new function memdup_array_user() instead of memdup_user() for
duplicating the user-space array safely.
Suggested-by: David Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Zack Rusin <zackr@vmware.com>
---
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 5db403ee8261..9be185b094cb 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -777,9 +777,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
sizeof(metadata->mip_levels));
metadata->num_sizes = num_sizes;
metadata->sizes =
- memdup_user((struct drm_vmw_size __user *)(unsigned long)
+ memdup_array_user((struct drm_vmw_size __user *)(unsigned long)
req->size_addr,
- sizeof(*metadata->sizes) * metadata->num_sizes);
+ metadata->num_sizes, sizeof(*metadata->sizes));
if (IS_ERR(metadata->sizes)) {
ret = PTR_ERR(metadata->sizes);
goto out_no_sizes;
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread