linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org,
	"Mauro Carvalho Chehab" <mchehab@s-opensource.com>,
	"Sakari Ailus" <sakari.ailus@linux.intel.com>,
	"Daniel Mentz" <danielmentz@google.com>,
	"Hans Verkuil" <hans.verkuil@cisco.com>
Subject: [PATCH 3.16 252/254] media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic
Date: Wed, 28 Feb 2018 15:20:18 +0000	[thread overview]
Message-ID: <lsq.1519831218.959316687@decadent.org.uk> (raw)
In-Reply-To: <lsq.1519831217.271785318@decadent.org.uk>

3.16.55-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Daniel Mentz <danielmentz@google.com>

commit a1dfb4c48cc1e64eeb7800a27c66a6f7e88d075a upstream.

The 32-bit compat v4l2 ioctl handling is implemented based on its 64-bit
equivalent. It converts 32-bit data structures into its 64-bit
equivalents and needs to provide the data to the 64-bit ioctl in user
space memory which is commonly allocated using
compat_alloc_user_space().

However, due to how that function is implemented, it can only be called
a single time for every syscall invocation.

Supposedly to avoid this limitation, the existing code uses a mix of
memory from the kernel stack and memory allocated through
compat_alloc_user_space().

Under normal circumstances, this would not work, because the 64-bit
ioctl expects all pointers to point to user space memory. As a
workaround, set_fs(KERNEL_DS) is called to temporarily disable this
extra safety check and allow kernel pointers. However, this might
introduce a security vulnerability: The result of the 32-bit to 64-bit
conversion is writeable by user space because the output buffer has been
allocated via compat_alloc_user_space(). A malicious user space process
could then manipulate pointers inside this output buffer, and due to the
previous set_fs(KERNEL_DS) call, functions like get_user() or put_user()
no longer prevent kernel memory access.

The new approach is to pre-calculate the total amount of user space
memory that is needed, allocate it using compat_alloc_user_space() and
then divide up the allocated memory to accommodate all data structures
that need to be converted.

An alternative approach would have been to retain the union type karg
that they allocated on the kernel stack in do_video_ioctl(), copy all
data from user space into karg and then back to user space. However, we
decided against this approach because it does not align with other
compat syscall implementations. Instead, we tried to replicate the
get_user/put_user pairs as found in other places in the kernel:

    if (get_user(clipcount, &up->clipcount) ||
        put_user(clipcount, &kp->clipcount)) return -EFAULT;

Notes from hans.verkuil@cisco.com:

This patch was taken from:
    https://github.com/LineageOS/android_kernel_samsung_apq8084/commit/97b733953c06e4f0398ade18850f0817778255f7

Clearly nobody could be bothered to upstream this patch or at minimum
tell us :-( We only heard about this a week ago.

This patch was rebased and cleaned up. Compared to the original I
also swapped the order of the convert_in_user arguments so that they
matched copy_in_user. It was hard to review otherwise. I also replaced
the ALLOC_USER_SPACE/ALLOC_AND_GET by a normal function.

Fixes: 6b5a9492ca ("v4l: introduce string control support.")

Signed-off-by: Daniel Mentz <danielmentz@google.com>
Co-developed-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
[bwh: Rebased on top of some earlier fixes]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -22,6 +22,14 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-ioctl.h>
 
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from)					\
+({									\
+	typeof(*from) __assign_tmp;					\
+									\
+	get_user(__assign_tmp, from) || put_user(__assign_tmp, to);	\
+})
+
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	long ret = -ENOIOCTLCMD;
@@ -35,12 +43,12 @@ static long native_ioctl(struct file *fi
 
 struct v4l2_clip32 {
 	struct v4l2_rect        c;
-	compat_caddr_t 		next;
+	compat_caddr_t		next;
 };
 
 struct v4l2_window32 {
 	struct v4l2_rect        w;
-	__u32		  	field;	/* enum v4l2_field */
+	__u32			field;	/* enum v4l2_field */
 	__u32			chromakey;
 	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
 	__u32			clipcount;
@@ -48,37 +56,41 @@ struct v4l2_window32 {
 	__u8                    global_alpha;
 };
 
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+static int get_v4l2_window32(struct v4l2_window __user *kp,
+			     struct v4l2_window32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
 {
 	struct v4l2_clip32 __user *uclips;
 	struct v4l2_clip __user *kclips;
 	compat_caddr_t p;
-	u32 n;
+	u32 clipcount;
 
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
-	    get_user(kp->field, &up->field) ||
-	    get_user(kp->chromakey, &up->chromakey) ||
-	    get_user(kp->clipcount, &up->clipcount) ||
-	    get_user(kp->global_alpha, &up->global_alpha))
+	    copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
+	    assign_in_user(&kp->field, &up->field) ||
+	    assign_in_user(&kp->chromakey, &up->chromakey) ||
+	    assign_in_user(&kp->global_alpha, &up->global_alpha) ||
+	    get_user(clipcount, &up->clipcount) ||
+	    put_user(clipcount, &kp->clipcount))
 		return -EFAULT;
-	if (kp->clipcount > 2048)
+	if (clipcount > 2048)
 		return -EINVAL;
-	if (!kp->clipcount) {
-		kp->clips = NULL;
-		return 0;
-	}
+	if (!clipcount)
+		return put_user(NULL, &kp->clips);
 
-	n = kp->clipcount;
 	if (get_user(p, &up->clips))
 		return -EFAULT;
 	uclips = compat_ptr(p);
-	kclips = compat_alloc_user_space(n * sizeof(*kclips));
-	kp->clips = kclips;
-	while (n--) {
+	if (aux_space < clipcount * sizeof(*kclips))
+		return -EFAULT;
+	kclips = aux_buf;
+	if (put_user(kclips, &kp->clips))
+		return -EFAULT;
+
+	while (clipcount--) {
 		if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
 			return -EFAULT;
-		if (put_user(n ? kclips + 1 : NULL, &kclips->next))
+		if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
 			return -EFAULT;
 		uclips++;
 		kclips++;
@@ -86,27 +98,28 @@ static int get_v4l2_window32(struct v4l2
 	return 0;
 }
 
-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+static int put_v4l2_window32(struct v4l2_window __user *kp,
+			     struct v4l2_window32 __user *up)
 {
 	struct v4l2_clip __user *kclips = kp->clips;
 	struct v4l2_clip32 __user *uclips;
-	u32 n = kp->clipcount;
 	compat_caddr_t p;
+	u32 clipcount;
 
-	if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
-	    put_user(kp->field, &up->field) ||
-	    put_user(kp->chromakey, &up->chromakey) ||
-	    put_user(kp->clipcount, &up->clipcount) ||
-	    put_user(kp->global_alpha, &up->global_alpha))
+	if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
+	    assign_in_user(&up->field, &kp->field) ||
+	    assign_in_user(&up->chromakey, &kp->chromakey) ||
+	    assign_in_user(&up->global_alpha, &kp->global_alpha) ||
+	    get_user(clipcount, &kp->clipcount) ||
+	    put_user(clipcount, &up->clipcount))
 		return -EFAULT;
-
-	if (!kp->clipcount)
+	if (!clipcount)
 		return 0;
 
 	if (get_user(p, &up->clips))
 		return -EFAULT;
 	uclips = compat_ptr(p);
-	while (n--) {
+	while (clipcount--) {
 		if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
 			return -EFAULT;
 		uclips++;
@@ -144,93 +157,150 @@ struct v4l2_create_buffers32 {
 	__u32			reserved[8];
 };
 
-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
+{
+	u32 type;
+
+	if (get_user(type, &up->type))
+		return -EFAULT;
+
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
+		u32 clipcount;
+
+		if (get_user(clipcount, &up->fmt.win.clipcount))
+			return -EFAULT;
+		if (clipcount > 2048)
+			return -EINVAL;
+		*size = clipcount * sizeof(struct v4l2_clip);
+		return 0;
+	}
+	default:
+		*size = 0;
+		return 0;
+	}
+}
+
+static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
 {
-	if (get_user(kp->type, &up->type))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
 		return -EFAULT;
+	return __bufsize_v4l2_format(up, size);
+}
 
-	switch (kp->type) {
+static int __get_v4l2_format32(struct v4l2_format __user *kp,
+			       struct v4l2_format32 __user *up,
+			       void __user *aux_buf, u32 aux_space)
+{
+	u32 type;
+
+	if (get_user(type, &up->type) || put_user(type, &kp->type))
+		return -EFAULT;
+
+	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return copy_from_user(&kp->fmt.pix, &up->fmt.pix,
-				      sizeof(kp->fmt.pix)) ? -EFAULT : 0;
+		return copy_in_user(&kp->fmt.pix, &up->fmt.pix,
+				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		return copy_from_user(&kp->fmt.pix_mp, &up->fmt.pix_mp,
-				      sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
+		return copy_in_user(&kp->fmt.pix_mp, &up->fmt.pix_mp,
+				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win,
+					 aux_buf, aux_space);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		return copy_from_user(&kp->fmt.vbi, &up->fmt.vbi,
-				      sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
+		return copy_in_user(&kp->fmt.vbi, &up->fmt.vbi,
+				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		return copy_from_user(&kp->fmt.sliced, &up->fmt.sliced,
-				      sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
+		return copy_in_user(&kp->fmt.sliced, &up->fmt.sliced,
+				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
 	default:
 		return -EINVAL;
 	}
 }
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format __user *kp,
+			     struct v4l2_format32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+		return -EFAULT;
+	return __get_v4l2_format32(kp, up, aux_buf, aux_space);
+}
+
+static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up,
+			       u32 *size)
 {
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
 		return -EFAULT;
-	return __get_v4l2_format32(kp, up);
+	return __bufsize_v4l2_format(&up->format, size);
 }
 
-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int get_v4l2_create32(struct v4l2_create_buffers __user *kp,
+			     struct v4l2_create_buffers32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
 {
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
+	    copy_in_user(kp, up,
+			 offsetof(struct v4l2_create_buffers32, format)))
 		return -EFAULT;
-	return __get_v4l2_format32(&kp->format, &up->format);
+	return __get_v4l2_format32(&kp->format, &up->format,
+				   aux_buf, aux_space);
 }
 
-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __put_v4l2_format32(struct v4l2_format __user *kp,
+			       struct v4l2_format32 __user *up)
 {
-	if (put_user(kp->type, &up->type))
+	u32 type;
+
+	if (get_user(type, &kp->type))
 		return -EFAULT;
 
-	switch (kp->type) {
+	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return copy_to_user(&up->fmt.pix, &kp->fmt.pix,
+		return copy_in_user(&up->fmt.pix, &kp->fmt.pix,
 				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		return copy_to_user(&up->fmt.pix_mp, &kp->fmt.pix_mp,
+		return copy_in_user(&up->fmt.pix_mp, &kp->fmt.pix_mp,
 				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
 		return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		return copy_to_user(&up->fmt.vbi, &kp->fmt.vbi,
+		return copy_in_user(&up->fmt.vbi, &kp->fmt.vbi,
 				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		return copy_to_user(&up->fmt.sliced, &kp->fmt.sliced,
+		return copy_in_user(&up->fmt.sliced, &kp->fmt.sliced,
 				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
 	default:
 		return -EINVAL;
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int put_v4l2_format32(struct v4l2_format __user *kp,
+			     struct v4l2_format32 __user *up)
 {
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
 		return -EFAULT;
 	return __put_v4l2_format32(kp, up);
 }
 
-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int put_v4l2_create32(struct v4l2_create_buffers __user *kp,
+			     struct v4l2_create_buffers32 __user *up)
 {
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+	    copy_in_user(up, kp,
+			 offsetof(struct v4l2_create_buffers32, format)) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
 		return -EFAULT;
 	return __put_v4l2_format32(&kp->format, &up->format);
 }
@@ -244,24 +314,27 @@ struct v4l2_standard32 {
 	__u32		     reserved[4];
 };
 
-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int get_v4l2_standard32(struct v4l2_standard __user *kp,
+			       struct v4l2_standard32 __user *up)
 {
 	/* other fields are not set by the user, nor used by the driver */
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    get_user(kp->index, &up->index))
+	    assign_in_user(&kp->index, &up->index))
 		return -EFAULT;
 	return 0;
 }
 
-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int put_v4l2_standard32(struct v4l2_standard __user *kp,
+			       struct v4l2_standard32 __user *up)
 {
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(kp->index, &up->index) ||
-	    put_user(kp->id, &up->id) ||
-	    copy_to_user(up->name, kp->name, sizeof(up->name)) ||
-	    copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
-	    put_user(kp->framelines, &up->framelines) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+	    assign_in_user(&up->index, &kp->index) ||
+	    assign_in_user(&up->id, &kp->id) ||
+	    copy_in_user(up->name, kp->name, sizeof(up->name)) ||
+	    copy_in_user(&up->frameperiod, &kp->frameperiod,
+			 sizeof(up->frameperiod)) ||
+	    assign_in_user(&up->framelines, &kp->framelines) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
 		return -EFAULT;
 	return 0;
 }
@@ -301,11 +374,11 @@ struct v4l2_buffer32 {
 	__u32			reserved;
 };
 
-static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+static int get_v4l2_plane32(struct v4l2_plane __user *up,
+			    struct v4l2_plane32 __user *up32,
 			    enum v4l2_memory memory)
 {
-	void __user *up_pln;
-	compat_long_t p;
+	compat_ulong_t p;
 
 	if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
 	    copy_in_user(&up->data_offset, &up32->data_offset,
@@ -320,10 +393,8 @@ static int get_v4l2_plane32(struct v4l2_
 			return -EFAULT;
 		break;
 	case V4L2_MEMORY_USERPTR:
-		if (get_user(p, &up32->m.userptr))
-			return -EFAULT;
-		up_pln = compat_ptr(p);
-		if (put_user((unsigned long)up_pln, &up->m.userptr))
+		if (get_user(p, &up32->m.userptr) ||
+		    put_user((unsigned long)compat_ptr(p), &up->m.userptr))
 			return -EFAULT;
 		break;
 	case V4L2_MEMORY_DMABUF:
@@ -335,7 +406,8 @@ static int get_v4l2_plane32(struct v4l2_
 	return 0;
 }
 
-static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+static int put_v4l2_plane32(struct v4l2_plane __user *up,
+			    struct v4l2_plane32 __user *up32,
 			    enum v4l2_memory memory)
 {
 	unsigned long p;
@@ -359,8 +431,7 @@ static int put_v4l2_plane32(struct v4l2_
 			return -EFAULT;
 		break;
 	case V4L2_MEMORY_DMABUF:
-		if (copy_in_user(&up32->m.fd, &up->m.fd,
-				 sizeof(up->m.fd)))
+		if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(up->m.fd)))
 			return -EFAULT;
 		break;
 	}
@@ -368,37 +439,75 @@ static int put_v4l2_plane32(struct v4l2_
 	return 0;
 }
 
-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size)
 {
+	u32 type;
+	u32 length;
+
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    get_user(type, &up->type) ||
+	    get_user(length, &up->length))
+		return -EFAULT;
+
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		if (length > VIDEO_MAX_PLANES)
+			return -EINVAL;
+
+		/*
+		 * We don't really care if userspace decides to kill itself
+		 * by passing a very big length value
+		 */
+		*size = length * sizeof(struct v4l2_plane);
+	} else {
+		*size = 0;
+	}
+	return 0;
+}
+
+static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
+			     struct v4l2_buffer32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
+{
+	u32 type;
+	u32 length;
+	enum v4l2_memory memory;
 	struct v4l2_plane32 __user *uplane32;
 	struct v4l2_plane __user *uplane;
 	compat_caddr_t p;
-	int num_planes;
 	int ret;
 
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    get_user(kp->index, &up->index) ||
-	    get_user(kp->type, &up->type) ||
-	    get_user(kp->flags, &up->flags) ||
-	    get_user(kp->memory, &up->memory) ||
-	    get_user(kp->length, &up->length))
-		return -EFAULT;
-
-	if (V4L2_TYPE_IS_OUTPUT(kp->type))
-		if (get_user(kp->bytesused, &up->bytesused) ||
-		    get_user(kp->field, &up->field) ||
-		    get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-		    get_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec))
+	    assign_in_user(&kp->index, &up->index) ||
+	    get_user(type, &up->type) ||
+	    put_user(type, &kp->type) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    get_user(memory, &up->memory) ||
+	    put_user(memory, &kp->memory) ||
+	    get_user(length, &up->length) ||
+	    put_user(length, &kp->length))
+		return -EFAULT;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		if (assign_in_user(&kp->bytesused, &up->bytesused) ||
+		    assign_in_user(&kp->field, &up->field) ||
+		    assign_in_user(&kp->timestamp.tv_sec,
+				   &up->timestamp.tv_sec) ||
+		    assign_in_user(&kp->timestamp.tv_usec,
+				   &up->timestamp.tv_usec))
 			return -EFAULT;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		num_planes = kp->length;
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		u32 num_planes = length;
+
 		if (num_planes == 0) {
-			kp->m.planes = NULL;
-			/* num_planes == 0 is legal, e.g. when userspace doesn't
-			 * need planes array on DQBUF*/
-			return 0;
+			/*
+			 * num_planes == 0 is legal, e.g. when userspace doesn't
+			 * need planes array on DQBUF
+			 */
+			return put_user(NULL, &kp->m.planes);
 		}
+		if (num_planes > VIDEO_MAX_PLANES)
+			return -EINVAL;
 
 		if (get_user(p, &up->m.planes))
 			return -EFAULT;
@@ -408,38 +517,43 @@ static int get_v4l2_buffer32(struct v4l2
 			       num_planes * sizeof(*uplane32)))
 			return -EFAULT;
 
-		/* We don't really care if userspace decides to kill itself
-		 * by passing a very big num_planes value */
-		uplane = compat_alloc_user_space(num_planes *
-						 sizeof(*uplane));
-		kp->m.planes = (__force struct v4l2_plane *)uplane;
+		/*
+		 * We don't really care if userspace decides to kill itself
+		 * by passing a very big num_planes value
+		 */
+		if (aux_space < num_planes * sizeof(*uplane))
+			return -EFAULT;
+
+		uplane = aux_buf;
+		if (put_user((__force struct v4l2_plane *)uplane,
+			     &kp->m.planes))
+			return -EFAULT;
 
-		while (--num_planes >= 0) {
-			ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
+		while (num_planes--) {
+			ret = get_v4l2_plane32(uplane, uplane32, memory);
 			if (ret)
 				return ret;
-			++uplane;
-			++uplane32;
+			uplane++;
+			uplane32++;
 		}
 	} else {
-		switch (kp->memory) {
+		switch (memory) {
 		case V4L2_MEMORY_MMAP:
 		case V4L2_MEMORY_OVERLAY:
-			if (get_user(kp->m.offset, &up->m.offset))
+			if (assign_in_user(&kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
-		case V4L2_MEMORY_USERPTR:
-			{
-				compat_long_t tmp;
+		case V4L2_MEMORY_USERPTR: {
+			compat_ulong_t userptr;
 
-				if (get_user(tmp, &up->m.userptr))
-					return -EFAULT;
-
-				kp->m.userptr = (unsigned long)compat_ptr(tmp);
-			}
+			if (get_user(userptr, &up->m.userptr) ||
+			    put_user((unsigned long)compat_ptr(userptr),
+				     &kp->m.userptr))
+				return -EFAULT;
 			break;
+		}
 		case V4L2_MEMORY_DMABUF:
-			if (get_user(kp->m.fd, &up->m.fd))
+			if (assign_in_user(&kp->m.fd, &up->m.fd))
 				return -EFAULT;
 			break;
 		}
@@ -448,62 +562,70 @@ static int get_v4l2_buffer32(struct v4l2
 	return 0;
 }
 
-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
+			     struct v4l2_buffer32 __user *up)
 {
+	u32 type;
+	u32 length;
+	enum v4l2_memory memory;
 	struct v4l2_plane32 __user *uplane32;
 	struct v4l2_plane __user *uplane;
 	compat_caddr_t p;
-	int num_planes;
 	int ret;
 
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(kp->index, &up->index) ||
-	    put_user(kp->type, &up->type) ||
-	    put_user(kp->flags, &up->flags) ||
-	    put_user(kp->memory, &up->memory))
-		return -EFAULT;
-
-	if (put_user(kp->bytesused, &up->bytesused) ||
-	    put_user(kp->field, &up->field) ||
-	    put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-	    put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
-	    copy_to_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
-	    put_user(kp->sequence, &up->sequence) ||
-	    put_user(kp->reserved2, &up->reserved2) ||
-	    put_user(kp->reserved, &up->reserved) ||
-	    put_user(kp->length, &up->length))
+	    assign_in_user(&up->index, &kp->index) ||
+	    get_user(type, &kp->type) ||
+	    put_user(type, &up->type) ||
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    get_user(memory, &kp->memory) ||
+	    put_user(memory, &up->memory))
+		return -EFAULT;
+
+	if (assign_in_user(&up->bytesused, &kp->bytesused) ||
+	    assign_in_user(&up->field, &kp->field) ||
+	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+	    assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) ||
+	    copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
+	    assign_in_user(&up->sequence, &kp->sequence) ||
+	    assign_in_user(&up->reserved2, &kp->reserved2) ||
+	    assign_in_user(&up->reserved, &kp->reserved) ||
+	    get_user(length, &kp->length) ||
+	    put_user(length, &up->length))
 		return -EFAULT;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		num_planes = kp->length;
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		u32 num_planes = length;
+
 		if (num_planes == 0)
 			return 0;
 
-		uplane = (__force struct v4l2_plane __user *)kp->m.planes;
+		if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
+			return -EFAULT;
 		if (get_user(p, &up->m.planes))
 			return -EFAULT;
 		uplane32 = compat_ptr(p);
 
-		while (--num_planes >= 0) {
-			ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
+		while (num_planes--) {
+			ret = put_v4l2_plane32(uplane, uplane32, memory);
 			if (ret)
 				return ret;
 			++uplane;
 			++uplane32;
 		}
 	} else {
-		switch (kp->memory) {
+		switch (memory) {
 		case V4L2_MEMORY_MMAP:
 		case V4L2_MEMORY_OVERLAY:
-			if (put_user(kp->m.offset, &up->m.offset))
+			if (assign_in_user(&up->m.offset, &kp->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
-			if (put_user(kp->m.userptr, &up->m.userptr))
+			if (assign_in_user(&up->m.userptr, &kp->m.userptr))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_DMABUF:
-			if (put_user(kp->m.fd, &up->m.fd))
+			if (assign_in_user(&up->m.fd, &kp->m.fd))
 				return -EFAULT;
 			break;
 		}
@@ -515,33 +637,45 @@ static int put_v4l2_buffer32(struct v4l2
 struct v4l2_framebuffer32 {
 	__u32			capability;
 	__u32			flags;
-	compat_caddr_t 		base;
-	struct v4l2_pix_format	fmt;
+	compat_caddr_t		base;
+	struct {
+		__u32		width;
+		__u32		height;
+		__u32		pixelformat;
+		__u32		field;
+		__u32		bytesperline;
+		__u32		sizeimage;
+		__u32		colorspace;
+		__u32		priv;
+	} fmt;
 };
 
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+				  struct v4l2_framebuffer32 __user *up)
 {
-	u32 tmp;
+	compat_caddr_t tmp;
 
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
 	    get_user(tmp, &up->base) ||
-	    get_user(kp->capability, &up->capability) ||
-	    get_user(kp->flags, &up->flags) ||
-	    copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
+	    put_user((__force void *)compat_ptr(tmp), &kp->base) ||
+	    assign_in_user(&kp->capability, &up->capability) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
 		return -EFAULT;
-	kp->base = (__force void *)compat_ptr(tmp);
 	return 0;
 }
 
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+				  struct v4l2_framebuffer32 __user *up)
 {
-	u32 tmp = (u32)((unsigned long)kp->base);
+	void *base;
 
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(tmp, &up->base) ||
-	    put_user(kp->capability, &up->capability) ||
-	    put_user(kp->flags, &up->flags) ||
-	    copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
+	    get_user(base, &kp->base) ||
+	    put_user(ptr_to_compat(base), &up->base) ||
+	    assign_in_user(&up->capability, &kp->capability) ||
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt)))
 		return -EFAULT;
 	return 0;
 }
@@ -558,18 +692,22 @@ struct v4l2_input32 {
 	__u32	     reserved[3];
 };
 
-/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
-   Otherwise it is identical to the 32-bit version. */
-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+/*
+ * The 64-bit v4l2_input struct has extra padding at the end of the struct.
+ * Otherwise it is identical to the 32-bit version.
+ */
+static inline int get_v4l2_input32(struct v4l2_input __user *kp,
+				   struct v4l2_input32 __user *up)
 {
-	if (copy_from_user(kp, up, sizeof(*up)))
+	if (copy_in_user(kp, up, sizeof(*up)))
 		return -EFAULT;
 	return 0;
 }
 
-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+static inline int put_v4l2_input32(struct v4l2_input __user *kp,
+				   struct v4l2_input32 __user *up)
 {
-	if (copy_to_user(up, kp, sizeof(*up)))
+	if (copy_in_user(up, kp, sizeof(*up)))
 		return -EFAULT;
 	return 0;
 }
@@ -616,40 +754,64 @@ static inline bool ctrl_is_pointer(struc
 	return false;
 }
 
+static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up,
+				     u32 *size)
+{
+	u32 count;
+
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    get_user(count, &up->count))
+		return -EFAULT;
+	if (count > V4L2_CID_MAX_CTRLS)
+		return -EINVAL;
+	*size = count * sizeof(struct v4l2_ext_control);
+	return 0;
+}
+
 static int get_v4l2_ext_controls32(struct file *file,
-				   struct v4l2_ext_controls *kp,
-				   struct v4l2_ext_controls32 __user *up)
+				   struct v4l2_ext_controls __user *kp,
+				   struct v4l2_ext_controls32 __user *up,
+				   void __user *aux_buf, u32 aux_space)
 {
 	struct v4l2_ext_control32 __user *ucontrols;
 	struct v4l2_ext_control __user *kcontrols;
-	int n;
+	u32 count;
+	u32 n;
 	compat_caddr_t p;
 
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    get_user(kp->ctrl_class, &up->ctrl_class) ||
-	    get_user(kp->count, &up->count) ||
-	    get_user(kp->error_idx, &up->error_idx) ||
-	    copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
-		return -EFAULT;
-	n = kp->count;
-	if (n == 0) {
-		kp->controls = NULL;
-		return 0;
-	}
+	    assign_in_user(&kp->ctrl_class, &up->ctrl_class) ||
+	    get_user(count, &up->count) ||
+	    put_user(count, &kp->count) ||
+	    assign_in_user(&kp->error_idx, &up->error_idx) ||
+	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+		return -EFAULT;
+
+	if (count == 0)
+		return put_user(NULL, &kp->controls);
+	if (count > V4L2_CID_MAX_CTRLS)
+		return -EINVAL;
 	if (get_user(p, &up->controls))
 		return -EFAULT;
 	ucontrols = compat_ptr(p);
-	if (!access_ok(VERIFY_READ, ucontrols, n * sizeof(*ucontrols)))
+	if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
+		return -EFAULT;
+	if (aux_space < count * sizeof(*kcontrols))
 		return -EFAULT;
-	kcontrols = compat_alloc_user_space(n * sizeof(*kcontrols));
-	kp->controls = (__force struct v4l2_ext_control *)kcontrols;
-	while (--n >= 0) {
+	kcontrols = aux_buf;
+	if (put_user((__force struct v4l2_ext_control *)kcontrols,
+		     &kp->controls))
+		return -EFAULT;
+
+	for (n = 0; n < count; n++) {
 		u32 id;
 
 		if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
 			return -EFAULT;
+
 		if (get_user(id, &kcontrols->id))
 			return -EFAULT;
+
 		if (ctrl_is_pointer(file, id)) {
 			void __user *s;
 
@@ -666,43 +828,54 @@ static int get_v4l2_ext_controls32(struc
 }
 
 static int put_v4l2_ext_controls32(struct file *file,
-				   struct v4l2_ext_controls *kp,
+				   struct v4l2_ext_controls __user *kp,
 				   struct v4l2_ext_controls32 __user *up)
 {
 	struct v4l2_ext_control32 __user *ucontrols;
-	struct v4l2_ext_control __user *kcontrols =
-		(__force struct v4l2_ext_control __user *)kp->controls;
-	int n = kp->count;
+	struct v4l2_ext_control __user *kcontrols;
+	u32 count;
+	u32 n;
 	compat_caddr_t p;
 
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(kp->ctrl_class, &up->ctrl_class) ||
-	    put_user(kp->count, &up->count) ||
-	    put_user(kp->error_idx, &up->error_idx) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+	    assign_in_user(&up->ctrl_class, &kp->ctrl_class) ||
+	    get_user(count, &kp->count) ||
+	    put_user(count, &up->count) ||
+	    assign_in_user(&up->error_idx, &kp->error_idx) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
+	    get_user(kcontrols, &kp->controls))
 		return -EFAULT;
-	if (!kp->count)
-		return 0;
 
+	if (!count)
+		return 0;
 	if (get_user(p, &up->controls))
 		return -EFAULT;
 	ucontrols = compat_ptr(p);
-	if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(*ucontrols)))
+	if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
 		return -EFAULT;
 
-	while (--n >= 0) {
-		unsigned size = sizeof(*ucontrols);
+	for (n = 0; n < count; n++) {
+		unsigned int size = sizeof(*ucontrols);
 		u32 id;
 
-		if (get_user(id, &kcontrols->id))
+		if (get_user(id, &kcontrols->id) ||
+		    put_user(id, &ucontrols->id) ||
+		    assign_in_user(&ucontrols->size, &kcontrols->size) ||
+		    copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
+				 sizeof(ucontrols->reserved2)))
 			return -EFAULT;
-		/* Do not modify the pointer when copying a pointer control.
-		   The contents of the pointer was changed, not the pointer
-		   itself. */
+
+		/*
+		 * Do not modify the pointer when copying a pointer control.
+		 * The contents of the pointer was changed, not the pointer
+		 * itself.
+		 */
 		if (ctrl_is_pointer(file, id))
 			size -= sizeof(ucontrols->value64);
+
 		if (copy_in_user(ucontrols, kcontrols, size))
 			return -EFAULT;
+
 		ucontrols++;
 		kcontrols++;
 	}
@@ -722,17 +895,18 @@ struct v4l2_event32 {
 	__u32				reserved[8];
 };
 
-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
+static int put_v4l2_event32(struct v4l2_event __user *kp,
+			    struct v4l2_event32 __user *up)
 {
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(kp->type, &up->type) ||
-	    copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
-	    put_user(kp->pending, &up->pending) ||
-	    put_user(kp->sequence, &up->sequence) ||
-	    put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-	    put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
-	    put_user(kp->id, &up->id) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+	    assign_in_user(&up->type, &kp->type) ||
+	    copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
+	    assign_in_user(&up->pending, &kp->pending) ||
+	    assign_in_user(&up->sequence, &kp->sequence) ||
+	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+	    assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) ||
+	    assign_in_user(&up->id, &kp->id) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
 		return -EFAULT;
 	return 0;
 }
@@ -745,31 +919,34 @@ struct v4l2_edid32 {
 	compat_caddr_t edid;
 };
 
-static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int get_v4l2_edid32(struct v4l2_edid __user *kp,
+			   struct v4l2_edid32 __user *up)
 {
-	u32 tmp;
+	compat_uptr_t tmp;
 
 	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
-	    get_user(kp->pad, &up->pad) ||
-	    get_user(kp->start_block, &up->start_block) ||
-	    get_user(kp->blocks, &up->blocks) ||
+	    assign_in_user(&kp->pad, &up->pad) ||
+	    assign_in_user(&kp->start_block, &up->start_block) ||
+	    assign_in_user(&kp->blocks, &up->blocks) ||
 	    get_user(tmp, &up->edid) ||
-	    copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+	    put_user(compat_ptr(tmp), &kp->edid) ||
+	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
 		return -EFAULT;
-	kp->edid = (__force u8 *)compat_ptr(tmp);
 	return 0;
 }
 
-static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int put_v4l2_edid32(struct v4l2_edid __user *kp,
+			   struct v4l2_edid32 __user *up)
 {
-	u32 tmp = (u32)((unsigned long)kp->edid);
+	void *edid;
 
 	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
-	    put_user(kp->pad, &up->pad) ||
-	    put_user(kp->start_block, &up->start_block) ||
-	    put_user(kp->blocks, &up->blocks) ||
-	    put_user(tmp, &up->edid) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+	    assign_in_user(&up->pad, &kp->pad) ||
+	    assign_in_user(&up->start_block, &kp->start_block) ||
+	    assign_in_user(&up->blocks, &kp->blocks) ||
+	    get_user(edid, &kp->edid) ||
+	    put_user(ptr_to_compat(edid), &up->edid) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
 		return -EFAULT;
 	return 0;
 }
@@ -786,7 +963,7 @@ static int put_v4l2_edid32(struct v4l2_e
 #define VIDIOC_ENUMINPUT32	_IOWR('V', 26, struct v4l2_input32)
 #define VIDIOC_G_EDID32		_IOWR('V', 40, struct v4l2_edid32)
 #define VIDIOC_S_EDID32		_IOWR('V', 41, struct v4l2_edid32)
-#define VIDIOC_TRY_FMT32      	_IOWR('V', 64, struct v4l2_format32)
+#define VIDIOC_TRY_FMT32	_IOWR('V', 64, struct v4l2_format32)
 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
@@ -802,22 +979,23 @@ static int put_v4l2_edid32(struct v4l2_e
 #define VIDIOC_G_OUTPUT32	_IOR ('V', 46, s32)
 #define VIDIOC_S_OUTPUT32	_IOWR('V', 47, s32)
 
+static int alloc_userspace(unsigned int size, u32 aux_space,
+			   void __user **up_native)
+{
+	*up_native = compat_alloc_user_space(size + aux_space);
+	if (!*up_native)
+		return -ENOMEM;
+	if (clear_user(*up_native, size))
+		return -EFAULT;
+	return 0;
+}
+
 static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	union {
-		struct v4l2_format v2f;
-		struct v4l2_buffer v2b;
-		struct v4l2_framebuffer v2fb;
-		struct v4l2_input v2i;
-		struct v4l2_standard v2s;
-		struct v4l2_ext_controls v2ecs;
-		struct v4l2_event v2ev;
-		struct v4l2_create_buffers v2crt;
-		struct v4l2_edid v2edid;
-		unsigned long vx;
-		int vi;
-	} karg;
 	void __user *up = compat_ptr(arg);
+	void __user *up_native = NULL;
+	void __user *aux_buf;
+	u32 aux_space;
 	int compatible_arg = 1;
 	long err = 0;
 
@@ -856,30 +1034,52 @@ static long do_video_ioctl(struct file *
 	case VIDIOC_STREAMOFF:
 	case VIDIOC_S_INPUT:
 	case VIDIOC_S_OUTPUT:
-		err = get_user(karg.vi, (s32 __user *)up);
+		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
+		if (!err && assign_in_user((unsigned int __user *)up_native,
+					   (compat_uint_t __user *)up))
+			err = -EFAULT;
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_INPUT:
 	case VIDIOC_G_OUTPUT:
+		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_EDID:
 	case VIDIOC_S_EDID:
-		err = get_v4l2_edid32(&karg.v2edid, up);
+		err = alloc_userspace(sizeof(struct v4l2_edid), 0, &up_native);
+		if (!err)
+			err = get_v4l2_edid32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_FMT:
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
-		err = get_v4l2_format32(&karg.v2f, up);
+		err = bufsize_v4l2_format(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_format),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_format);
+			err = get_v4l2_format32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_CREATE_BUFS:
-		err = get_v4l2_create32(&karg.v2crt, up);
+		err = bufsize_v4l2_create(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_create_buffers),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_create_buffers);
+			err = get_v4l2_create32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
@@ -887,36 +1087,63 @@ static long do_video_ioctl(struct file *
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
-		err = get_v4l2_buffer32(&karg.v2b, up);
+		err = bufsize_v4l2_buffer(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_buffer),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_buffer);
+			err = get_v4l2_buffer32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_S_FBUF:
-		err = get_v4l2_framebuffer32(&karg.v2fb, up);
+		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+				      &up_native);
+		if (!err)
+			err = get_v4l2_framebuffer32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_FBUF:
+		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+				      &up_native);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_ENUMSTD:
-		err = get_v4l2_standard32(&karg.v2s, up);
+		err = alloc_userspace(sizeof(struct v4l2_standard), 0,
+				      &up_native);
+		if (!err)
+			err = get_v4l2_standard32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_ENUMINPUT:
-		err = get_v4l2_input32(&karg.v2i, up);
+		err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native);
+		if (!err)
+			err = get_v4l2_input32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_EXT_CTRLS:
 	case VIDIOC_S_EXT_CTRLS:
 	case VIDIOC_TRY_EXT_CTRLS:
-		err = get_v4l2_ext_controls32(file, &karg.v2ecs, up);
+		err = bufsize_v4l2_ext_controls(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_ext_controls),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_ext_controls);
+			err = get_v4l2_ext_controls32(file, up_native, up,
+						      aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 	case VIDIOC_DQEVENT:
+		err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native);
 		compatible_arg = 0;
 		break;
 	}
@@ -925,25 +1152,26 @@ static long do_video_ioctl(struct file *
 
 	if (compatible_arg)
 		err = native_ioctl(file, cmd, (unsigned long)up);
-	else {
-		mm_segment_t old_fs = get_fs();
-
-		set_fs(KERNEL_DS);
-		err = native_ioctl(file, cmd, (unsigned long)&karg);
-		set_fs(old_fs);
-	}
+	else
+		err = native_ioctl(file, cmd, (unsigned long)up_native);
 
 	if (err == -ENOTTY)
 		return err;
 
-	/* Special case: even after an error we need to put the
-	   results back for these ioctls since the error_idx will
-	   contain information on which control failed. */
+	/*
+	 * Special case: even after an error we need to put the
+	 * results back for these ioctls since the error_idx will
+	 * contain information on which control failed.
+	 */
 	switch (cmd) {
 	case VIDIOC_G_EXT_CTRLS:
 	case VIDIOC_S_EXT_CTRLS:
 	case VIDIOC_TRY_EXT_CTRLS:
-		if (put_v4l2_ext_controls32(file, &karg.v2ecs, up))
+		if (put_v4l2_ext_controls32(file, up_native, up))
+			err = -EFAULT;
+		break;
+	case VIDIOC_S_EDID:
+		if (put_v4l2_edid32(up_native, up))
 			err = -EFAULT;
 		break;
 	}
@@ -955,45 +1183,46 @@ static long do_video_ioctl(struct file *
 	case VIDIOC_S_OUTPUT:
 	case VIDIOC_G_INPUT:
 	case VIDIOC_G_OUTPUT:
-		err = put_user(((s32)karg.vi), (s32 __user *)up);
+		if (assign_in_user((compat_uint_t __user *)up,
+				   ((unsigned int __user *)up_native)))
+			err = -EFAULT;
 		break;
 
 	case VIDIOC_G_FBUF:
-		err = put_v4l2_framebuffer32(&karg.v2fb, up);
+		err = put_v4l2_framebuffer32(up_native, up);
 		break;
 
 	case VIDIOC_DQEVENT:
-		err = put_v4l2_event32(&karg.v2ev, up);
+		err = put_v4l2_event32(up_native, up);
 		break;
 
 	case VIDIOC_G_EDID:
-	case VIDIOC_S_EDID:
-		err = put_v4l2_edid32(&karg.v2edid, up);
+		err = put_v4l2_edid32(up_native, up);
 		break;
 
 	case VIDIOC_G_FMT:
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
-		err = put_v4l2_format32(&karg.v2f, up);
+		err = put_v4l2_format32(up_native, up);
 		break;
 
 	case VIDIOC_CREATE_BUFS:
-		err = put_v4l2_create32(&karg.v2crt, up);
+		err = put_v4l2_create32(up_native, up);
 		break;
 
 	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
-		err = put_v4l2_buffer32(&karg.v2b, up);
+		err = put_v4l2_buffer32(up_native, up);
 		break;
 
 	case VIDIOC_ENUMSTD:
-		err = put_v4l2_standard32(&karg.v2s, up);
+		err = put_v4l2_standard32(up_native, up);
 		break;
 
 	case VIDIOC_ENUMINPUT:
-		err = put_v4l2_input32(&karg.v2i, up);
+		err = put_v4l2_input32(up_native, up);
 		break;
 	}
 	return err;

  parent reply	other threads:[~2018-02-28 16:16 UTC|newest]

Thread overview: 261+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-28 15:20 [PATCH 3.16 000/254] 3.16.55-rc1 review Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 138/254] iw_cxgb4: Only validate the MSN for successful completions Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 046/254] xhci: Don't show incorrect WARN message about events for empty rings Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 183/254] mdio-sun4i: Fix a memory leak Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 007/254] btrfs: clear space cache inode generation always Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 008/254] scsi: dma-mapping: always provide dma_get_cache_alignment Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 253/254] ACPI: sbshc: remove raw pointer from printk() message Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 032/254] eeprom: at24: check at24_read/write arguments Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 098/254] MIPS: Set `si_code' for SIGFPE signals sent from emulation too Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 195/254] net: ipv4: emulate READ_ONCE() on ->hdrincl bit-field in raw_sendmsg() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 071/254] ASN.1: fix out-of-bounds read when parsing indefinite length item Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 018/254] drm/i915: Don't try indexed reads to alternate slave addresses Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 199/254] powerpc: Don't preempt_disable() in show_cpuinfo() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 134/254] net/mlx5: Cleanup IRQs in case of unload failure Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 059/254] x86/PCI: Make broadcom_postcore_init() check acpi_disabled Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 120/254] PCI / PM: Force devices to D0 in pci_pm_thaw_noirq() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 249/254] media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 005/254] KVM: x86: Don't re-execute instruction when not passing CR2 value Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 054/254] dm: fix various targets to dm_register_target after module __init resources created Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 044/254] can: ti_hecc: Fix napi poll return value for repoll Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 026/254] uas: Always apply US_FL_NO_ATA_1X quirk to Seagate devices Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 090/254] tcp md5sig: Use skb's saddr when replying to an incoming segment Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 089/254] ext4: fix crash when a directory's i_size is too small Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 042/254] can: kvaser_usb: Fix comparison bug in kvaser_usb_read_bulk_callback() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 229/254] dccp: don't restart ccid2_hc_tx_rto_expire() if sk in closed state Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 004/254] KVM: x86: emulator: Return to user-mode on L1 CPL=0 emulation failure Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 102/254] MIPS: ptrace: Fix FP context restoration FCSR regression Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 231/254] of: fdt: Fix return with value in void function Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 232/254] net: bcmgenet: fix bcmgenet_open() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 198/254] ALSA: hda - Apply the existing quirk to iMac 14,1 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 035/254] quota: Check for register_shrinker() failure Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 165/254] net: phy: Add phy_interface_is_rgmii helper Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 200/254] 8021q: fix a memory leak for VLAN 0 device Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 185/254] Input: twl4030-vibra - fix ERROR: Bad of_node_put() warning Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 215/254] dm btree: fix serious bug in btree_split_beneath() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 192/254] USB: Gadget core: fix inconsistency in the interface tousb_add_gadget_udc_release() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 086/254] ipv4: Use standard iovec primitive in raw_probe_proto_opt Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 101/254] MIPS: Fix a preemption issue with thread's FPU defaults Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 028/254] isa: Prevent NULL dereference in isa_bus driver callbacks Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 093/254] MIPS: Clear [MSA]FPE CSR.Cause after notify_die() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 097/254] MIPS: Always clear FCSR cause bits after emulation Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 096/254] MIPS: Respect the FCSR exception mask for `si_code' Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 210/254] sctp: return error if the asoc has been peeled off in sctp_wait_for_sndbuf Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 104/254] MIPS: MSA: bugfix - disable MSA correctly for new threads/processes Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 162/254] can: gs_usb: fix return value of the "set_bittiming" callback Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 164/254] usbip: remove kernel addresses from usb device and urb debug msgs Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 248/254] media: v4l2-compat-ioctl32: Copy v4l2_window->global_alpha Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 170/254] mm/mprotect: add a cond_resched() inside change_pmd_range() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 077/254] usb: musb: da8xx: fix babble condition handling Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 113/254] ALSA: rawmidi: Avoid racy info ioctl via ctl device Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 240/254] media: v4l2-ioctl.c: don't copy back the result for -ENOTTY Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 045/254] virtio: release virtio index when fail to device_register Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 109/254] MIPS: Fix an FCSR access API regression with NT_PRFPREG and MSA Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 205/254] nl80211: take RCU read lock when calling ieee80211_bss_get_ie() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 201/254] ALSA: pcm: Remove yet superfluous WARN_ON() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 061/254] efi: Move some sysfs files to be read-only by root Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 173/254] ARM: dts: kirkwood: fix pin-muxing of MPP7 on OpenBlocks A7 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 145/254] tracing: Fix crash when it fails to alloc ring buffer Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 022/254] usb: host: fix incorrect updating of offset Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 235/254] [media] v4l2-compat-ioctl32: fix sparse warnings Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 143/254] sctp: Replace use of sockets_allocated with specified macro Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 151/254] af_key: fix buffer overread in parse_exthdrs() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 072/254] ASN.1: check for error from ASN1_OP_END__ACT actions Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 221/254] cfg80211: fix station info handling bugs Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 123/254] net: bridge: fix early call to br_stp_change_bridge_id and plug newlink leaks Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 139/254] crypto: n2 - cure use after free Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 100/254] MIPS: Respect the ISA level in FCSR handling Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 153/254] USB: serial: cp210x: add IDs for LifeScan OneTouch Verio IQ Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 158/254] e1000e: Fix e1000_check_for_copper_link_ich8lan return value Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 030/254] sctp: force the params with right types for sctp csum apis Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 106/254] mips/ptrace: Preserve previous registers for short regset write Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 222/254] x86/mce: Make machine check speculation protected Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 052/254] batman-adv: Fix lock for ogm cnt access in batadv_iv_ogm_calc_tq Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 207/254] cfg80211: check dev_set_name() return value Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 171/254] crypto: algapi - fix NULL dereference in crypto_remove_spawns() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 124/254] ALSA: usb-audio: Fix the missing ctl name suffix at parsing SU Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 024/254] usb: hub: Cycle HUB power when initialization fails Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 119/254] KVM: arm/arm64: Fix HYP unmapping going off limits Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 211/254] sctp: do not allow the v4 socket to bind a v4mapped v6 address Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 227/254] pppoe: take ->needed_headroom of lower device into account on xmit Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 049/254] ALSA: usb-audio: Fix out-of-bound error Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 136/254] net: mvneta: clear interface link status on port disable Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 110/254] MIPS: Disallow outsized PTRACE_SETREGSET NT_PRFPREG regset accesses Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 191/254] usb: udc: core: add device_del() call to error pathway Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 094/254] MIPS: prevent FP context set via ptrace being discarded Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 246/254] media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 088/254] net: ipv4: fix for a race condition in raw_sendmsg Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 036/254] mfd: cros ec: spi: Don't send first message too soon Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 002/254] ASoC: twl4030: fix child-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 243/254] media: v4l2-compat-ioctl32.c: fix the indentation Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 168/254] sh_eth: fix TSU resource handling Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 085/254] nl80211: fix nl80211_send_iface() error paths Ben Hutchings
2018-02-28 15:20 ` Ben Hutchings [this message]
2018-02-28 15:20 ` [PATCH 3.16 063/254] btrfs: fix missing error return in btrfs_drop_snapshot Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 181/254] ALSA: pcm: Abort properly at pending signal in OSS read/write loops Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 214/254] dm thin metadata: THIN_MAX_CONCURRENT_LOCKS should be 6 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 076/254] 509: fix printing uninitialized stack memory when OID is empty Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 130/254] usbip: fix usbip bind writing random string after command in match_busid Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 068/254] can: esd_usb2: cancel urb on -EPIPE and -EPROTO Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 062/254] kdb: Fix handling of kallsyms_symbol_next() return value Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 177/254] ALSA: aloop: Fix racy hw constraints adjustment Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 129/254] usbip: prevent leaking socket pointer address in messages Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 121/254] ACPI: APEI / ERST: Fix missing error handling in erst_reader() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 176/254] ALSA: aloop: Fix inconsistent format due to incomplete rule Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 180/254] xfrm: Return error on unknown encap_type in init_state Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 064/254] Btrfs: disable FUA if mounted with nobarrier Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 239/254] adv7604: use correct drive strength defines Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 184/254] sh_eth: fix TXALCR1 offsets Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 010/254] scsi: libsas: align sata_device's rps_resp on a cacheline Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 118/254] parisc: Hide Diva-built-in serial aux and graphics card Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 095/254] MIPS: lose_fpu(): Disable FPU when MSA enabled Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 070/254] can: usb_8dev: cancel urb on -EPIPE and -EPROTO Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 039/254] ALSA: seq: Remove spurious WARN_ON() at timer check Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 169/254] kernel/acct.c: fix the acct->needcheck check in check_free_space() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 247/254] media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 016/254] blktrace: fix trace mutex deadlock Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 179/254] x86/microcode/intel: Extend BDW late-loading with a revision check Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 006/254] iommu/vt-d: Fix scatterlist offset handling Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 238/254] media: v4l2-compat-ioctl32.c: add capabilities field to, v4l2_input32 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 209/254] sctp: use the right sk after waking up from wait_buf sleep Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 188/254] Input: twl6040-vibra - fix child-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 174/254] x86/alternatives: Add missing '\n' at end of ALTERNATIVE inline asm Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 082/254] dmaengine: dmatest: warn user when dma test times out Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 146/254] tracing: Fix possible double free on failure of allocating trace buffer Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 234/254] blk-mq: fix race between timeout and freeing request Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 159/254] IB/srpt: Disable RDMA access by the initiator Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 218/254] net: fs_enet: do not call phy_stop() in interrupts Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 161/254] USB: serial: cp210x: add new device ID ELV ALC 8xxx Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 083/254] dmaengine: dmatest: move callback wait queue to thread context Ben Hutchings
2018-02-28 17:47   ` Adam Wallis
2018-03-03 15:33     ` Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 251/254] media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 099/254] MIPS: math-emu: Define IEEE 754-2008 feature control bits Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 144/254] ring-buffer: Mask out the info bits when returning buffer page length Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 025/254] usb: quirks: Add no-lpm quirk for KY-688 USB 3.1 Type-C Hub Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 020/254] usb: gadget: don't dereference g until after it has been null checked Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 148/254] include/stddef.h: Move offsetofend() from vfio.h to a generic kernel header Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 133/254] net/mlx5: Fix misspelling in the error message and comment Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 067/254] can: ems_usb: cancel urb on -EPIPE and -EPROTO Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 111/254] powerpc/perf: Dereference BHRB entries safely Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 194/254] uas: ignore UAS for Norelsys NS1068(X) chips Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 021/254] USB: usbfs: Filter flags passed in from user space Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 241/254] vb2: V4L2_BUF_FLAG_DONE is set after DQBUF Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 156/254] IB/ipoib: Fix race condition in neigh creation Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 154/254] fscache: Fix the default for fscache_maybe_release_page() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 011/254] bcache: recover data from backing when data is clean Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 189/254] Input: 88pm860x-ts - fix child-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 132/254] usb: Add device quirk for Logitech HD Pro Webcam C925e Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 013/254] USB: serial: option: add Quectel BG96 id Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 244/254] media: v4l2-compat-ioctl32.c: move 'helper' functions to __get/put_v4l2_format32 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 038/254] mfd: twl6040: Fix child-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 220/254] can: af_can: canfd_rcv(): replace WARN_ONCE by pr_warn_once Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 197/254] SolutionEngine771x: add Ether TSU resource Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 078/254] USB: uas and storage: Add US_FL_BROKEN_FUA for another JMicron JMS567 ID Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 141/254] USB: serial: ftdi_sio: add id for Airbus DS P8GR Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 091/254] MIPS: CPS: Fix r1 .set mt assembler warning Ben Hutchings
2018-03-01 13:44   ` James Hogan
2018-03-03 15:48     ` Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 033/254] arm64: KVM: fix VTTBR_BADDR_MASK BUG_ON off-by-one Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 073/254] lib/oid_registry.c: X.509: fix the buffer overflow in the utility function for OID string Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 115/254] nfsd: auth: Fix gid sorting when rootsquash enabled Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 040/254] media: dvb: i2c transfers over usb cannot be done from stack Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 015/254] ASoC: fsl_ssi: AC'97 ops need regmap, clock and cleaning up on failure Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 155/254] ALSA: pcm: Remove incorrect snd_BUG_ON() usages Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 142/254] usb: xhci: Add XHCI_TRUST_TX_LENGTH for Renesas uPD720201 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 057/254] net_sched: red: Avoid illegal values Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 152/254] kbuild: add '-fno-stack-check' to kernel build options Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 034/254] arm: KVM: Fix VTTBR_BADDR_MASK BUG_ON off-by-one Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 223/254] net: igmp: Use correct source address on IGMPv3 reports Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 186/254] Input: twl4030-vibra - fix sibling-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 206/254] mac80211_hwsim: validate number of different channels Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 254/254] rds: Fix NULL pointer dereference in __rds_rdma_map Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 213/254] KVM/x86: Fix wrong macro references of X86_CR0_PG_BIT and X86_CR4_PAE_BIT in kvm_valid_sregs() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 175/254] ALSA: aloop: Release cable upon open error path Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 202/254] KVM: x86: Add memory barrier on vmcs field lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 023/254] USB: core: Add type-specific length check of BOS descriptors Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 147/254] nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 066/254] net: mvmdio: disable/unprepare clocks in EPROBE_DEFER case Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 237/254] [media] media: v4l2-compat-ioctl32: fix missing reserved field copy in put_v4l2_create32 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 225/254] Input: trackpoint - assume 3 buttons when buttons detection fails Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 112/254] KVM: X86: Fix load RFLAGS w/o the fixed bit Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 041/254] can: kvaser_usb: free buf in error paths Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 012/254] Input: elantech - add new icbody type 15 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 107/254] MIPS: Factor out NT_PRFPREG regset access helpers Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 172/254] xfrm: Use __skb_queue_tail in xfrm_trans_queue Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 031/254] net/packet: fix a race in packet_bind() and packet_notifier() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 233/254] mac80211_hwsim: fix compiler warning on MIPS Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 160/254] mmc: s3mci: mark debug_regs[] as static Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 103/254] MIPS: ptrace: Prevent writes to read-only FCSR bits Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 187/254] Input: twl6040-vibra - fix DT node memory management Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 167/254] net: stmmac: enable EEE in MII, GMII or RGMII only Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 204/254] futex: Prevent overflow by strengthen input validation Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 043/254] can: kvaser_usb: ratelimit errors if incomplete messages are received Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 079/254] ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 212/254] KVM/x86: Check input paging mode when cs.l is set Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 058/254] ALSA: pcm: prevent UAF in snd_pcm_info Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 029/254] hv: kvp: Avoid reading past allocated blocks from KVP file Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 166/254] phy: Add helper function to check phy interface mode Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 051/254] netfilter: xt_bpf: add overflow checks Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 230/254] hrtimer: Reset hrtimer cpu base proper on CPU hotplug Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 001/254] ALSA: seq: Fix regression by incorrect ioctl_mutex usages Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 157/254] e1000e: Separate signaling for link check/link up Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 135/254] net/mlx5: Stay in polling mode when command EQ destroy fails Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 219/254] can: af_can: can_rcv(): replace WARN_ONCE by pr_warn_once Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 017/254] hwmon: (pmbus) Use 64bit math for DIRECT format values Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 224/254] net: igmp: fix source address check for IGMPv3 reports Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 245/254] media: v4l2-compat-ioctl32.c: avoid sizeof(type) Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 117/254] posix-timer: Properly check sigevent->sigev_notify Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 182/254] ALSA: pcm: Allow aborting mutex lock at OSS read/write loops Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 203/254] usb: misc: usb3503: make sure reset is low for at least 100us Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 060/254] arm64: fpsimd: Prevent registers leaking from dead tasks Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 105/254] MIPS: Fix FCSR Cause bit handling for correct SIGFPE issue Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 092/254] MIPS: clear MSACSR cause bits when handling MSA FP exception Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 127/254] usbip: vhci: stop printing kernel pointer addresses in messages Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 116/254] USB: serial: option: add support for Telit ME910 PID 0x1101 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 217/254] i2c: core-smbus: prevent stack corruption on read I2C_BLOCK_DATA Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 126/254] USB: serial: option: adding support for YUGA CLM920-NC5 Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 122/254] net: phy: marvell: Limit 88m1101 autoneg errata to 88E1145 as well Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 137/254] n_tty: fix EXTPROC vs ICANON interaction with TIOCINQ (aka FIONREAD) Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 131/254] usb: add RESET_RESUME for ELSA MicroLink 56K Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 140/254] ALSA: hda - Add MIC_NO_PRESENCE fixup for 2 HP machines Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 080/254] ASoC: wm_adsp: Fix validation of firmware and coeff lengths Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 150/254] af_key: fix buffer overread in verify_address_len() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 163/254] ALSA: pcm: Add missing error checks in OSS emulation plugin builder Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 190/254] USB: fix usbmon BUG trigger Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 074/254] X.509: reject invalid BIT STRING for subjectPublicKey Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 019/254] drm/i915: Prevent zero length "index" write Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 128/254] usbip: stub: stop printing kernel pointer addresses in messages Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 193/254] USB: UDC core: fix double-free in usb_add_gadget_udc_release Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 216/254] i2c: core: decrease reference count of device node in i2c_unregister_device Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 056/254] net_sched: red: Avoid devision by zero Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 208/254] arm64: KVM: Fix SMCCC handling of unimplemented SMC/HVC calls Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 075/254] X.509: fix buffer overflow detection in sprint_oid() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 053/254] dm mpath: simplify failure path of dm_multipath_init() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 037/254] mfd: twl4030-audio: Fix sibling-node lookup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 149/254] stddef.h: move offsetofend inside #ifndef/#endif guard, neaten Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 114/254] kernel: make groups_sort calling a responsibility group_info allocators Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 226/254] Input: trackpoint - force 3 buttons if 0 button is reported Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 242/254] media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 125/254] xfrm: Reinject transport-mode packets through tasklet Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 014/254] ASoC: fsl_ssi: add AC'97 ops setting check and cleanup Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 236/254] [media] V4L2: fix VIDIOC_CREATE_BUFS 32-bit compatibility mode data copy-back Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 069/254] can: kvaser_usb: cancel urb on -EPIPE and -EPROTO Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 108/254] MIPS: Guard against any partial write attempt with PTRACE_SETREGSET Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 084/254] dmaengine: jz4740: disable/unprepare clk if probe fails Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 047/254] usb: xhci: fix panic in xhci_free_virt_devices_depth_first Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 196/254] SolutionEngine771x: fix Ether platform data Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 055/254] s390: always save and restore all registers on context switch Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 050/254] ALSA: usb-audio: Add check return value for usb_string() Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 027/254] serial: 8250_pci: Add Amazon PCI serial device ID Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 009/254] scsi: use dma_get_cache_alignment() as minimum DMA alignment Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 228/254] x86/microcode/intel: Extend BDW late-loading further with LLC size check Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 065/254] btrfs: Fix possible off-by-one in btrfs_search_path_in_tree Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 178/254] sh_eth: fix SH7757 GEther initialization Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 081/254] xhci: Don't add a virt_dev to the devs array before it's fully allocated Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 003/254] KVM: x86: Exit to user-mode on #UD intercept when emulator requires Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 250/254] media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 048/254] ext4: fix fdatasync(2) after fallocate(2) operation Ben Hutchings
2018-02-28 15:20 ` [PATCH 3.16 087/254] ipv4: Avoid reading user iov twice after raw_probe_proto_opt Ben Hutchings
2018-02-28 16:57 ` [PATCH 3.16 000/254] 3.16.55-rc1 review Guenter Roeck
2018-02-28 17:30   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1519831218.959316687@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=danielmentz@google.com \
    --cc=hans.verkuil@cisco.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mchehab@s-opensource.com \
    --cc=sakari.ailus@linux.intel.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).