Commit 11ae5eb5 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'topic/vmemdup-user-array-2023-10-24-1' of...

Merge tag 'topic/vmemdup-user-array-2023-10-24-1' of git://anongit.freedesktop.org/drm/drm

 into drm-next

vmemdup-user-array API and changes with it.

This is just a process PR to merge the topic branch into drm-next, this contains some core kernel and drm changes.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231024010905.646830-1-airlied@redhat.com
parents 3f5ba636 06ab64a0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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 −2
Original line number Diff line number Diff line
@@ -774,9 +774,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;
+40 −0
Original line number Diff line number Diff line
@@ -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
 */
+1 −1
Original line number Diff line number Diff line
@@ -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);

+1 −1
Original line number Diff line number Diff line
@@ -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);