Re: [PATCH 06/12] v4l2-compat-ioctl32.c: avoid sizeof(type)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 26, 2018 at 01:43:21PM +0100, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@xxxxxxxxx>
> 
> Instead of doing sizeof(struct foo) use sizeof(*up). There even were
> cases where 4 * sizeof(__u32) was used instead of sizeof(kp->reserved),
> which is very dangerous when the size of the reserved array changes.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>

Acked-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>

> ---
>  drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 77 ++++++++++++---------------
>  1 file changed, 35 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
> index 2dd9b42d5859..809448d1b7db 100644
> --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
> +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
> @@ -48,7 +48,7 @@ struct v4l2_window32 {
>  
>  static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
>  {
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
> +	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) ||
> @@ -66,7 +66,7 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
>  		if (get_user(p, &up->clips))
>  			return -EFAULT;
>  		uclips = compat_ptr(p);
> -		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
> +		kclips = compat_alloc_user_space(n * sizeof(*kclips));
>  		kp->clips = kclips;
>  		while (--n >= 0) {
>  			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
> @@ -164,14 +164,14 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
>  
>  static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
> +	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
>  		return -EFAULT;
>  	return __get_v4l2_format32(kp, up);
>  }
>  
>  static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
>  {
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
> +	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
>  	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
>  		return -EFAULT;
>  	return __get_v4l2_format32(&kp->format, &up->format);
> @@ -218,14 +218,14 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
>  
>  static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)))
> +	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)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
> +	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)))
>  		return -EFAULT;
> @@ -244,7 +244,7 @@ struct v4l2_standard32 {
>  static int get_v4l2_standard32(struct v4l2_standard *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(struct v4l2_standard32)) ||
> +	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
>  	    get_user(kp->index, &up->index))
>  		return -EFAULT;
>  	return 0;
> @@ -252,14 +252,14 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
>  
>  static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
> +	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, 24) ||
>  	    copy_to_user(&up->frameperiod, &kp->frameperiod,
>  			 sizeof(kp->frameperiod)) ||
>  	    put_user(kp->framelines, &up->framelines) ||
> -	    copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
> +	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
>  		return -EFAULT;
>  	return 0;
>  }
> @@ -307,7 +307,7 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __
>  
>  	if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
>  	    copy_in_user(&up->data_offset, &up32->data_offset,
> -			 sizeof(__u32)))
> +			 sizeof(up->data_offset)))
>  		return -EFAULT;
>  
>  	if (memory == V4L2_MEMORY_USERPTR) {
> @@ -317,11 +317,11 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __
>  		if (put_user((unsigned long)up_pln, &up->m.userptr))
>  			return -EFAULT;
>  	} else if (memory == V4L2_MEMORY_DMABUF) {
> -		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
> +		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd)))
>  			return -EFAULT;
>  	} else {
>  		if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
> -				 sizeof(__u32)))
> +				 sizeof(up32->m.mem_offset)))
>  			return -EFAULT;
>  	}
>  
> @@ -333,19 +333,19 @@ static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __
>  {
>  	if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
>  	    copy_in_user(&up32->data_offset, &up->data_offset,
> -			 sizeof(__u32)))
> +			 sizeof(up->data_offset)))
>  		return -EFAULT;
>  
>  	/* For MMAP, driver might've set up the offset, so copy it back.
>  	 * USERPTR stays the same (was userspace-provided), so no copying. */
>  	if (memory == V4L2_MEMORY_MMAP)
>  		if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
> -				 sizeof(__u32)))
> +				 sizeof(up->m.mem_offset)))
>  			return -EFAULT;
>  	/* For DMABUF, driver might've set up the fd, so copy it back. */
>  	if (memory == V4L2_MEMORY_DMABUF)
>  		if (copy_in_user(&up32->m.fd, &up->m.fd,
> -				 sizeof(int)))
> +				 sizeof(up->m.fd)))
>  			return -EFAULT;
>  
>  	return 0;
> @@ -358,7 +358,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
>  	compat_caddr_t p;
>  	int ret;
>  
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
> +	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) ||
> @@ -370,8 +370,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
>  		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))
> +		    get_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec))
>  			return -EFAULT;
>  
>  	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
> @@ -391,13 +390,12 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
>  
>  		uplane32 = compat_ptr(p);
>  		if (!access_ok(VERIFY_READ, uplane32,
> -			       kp->length * sizeof(struct v4l2_plane32)))
> +			       kp->length * 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(kp->length *
> -						 sizeof(struct v4l2_plane));
> +		uplane = compat_alloc_user_space(kp->length * sizeof(*uplane));
>  		kp->m.planes = (__force struct v4l2_plane *)uplane;
>  
>  		for (num_planes = 0; num_planes < kp->length; num_planes++) {
> @@ -445,7 +443,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
>  	int num_planes;
>  	int ret;
>  
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
> +	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) ||
> @@ -456,8 +454,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
>  	    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(struct v4l2_timecode)) ||
> +	    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) ||
> @@ -525,7 +522,7 @@ static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
>  {
>  	u32 tmp;
>  
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
> +	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) ||
> @@ -539,7 +536,7 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
>  {
>  	u32 tmp = (u32)((unsigned long)kp->base);
>  
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
> +	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) ||
> @@ -564,14 +561,14 @@ struct v4l2_input32 {
>     Otherwise it is identical to the 32-bit version. */
>  static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
>  {
> -	if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
> +	if (copy_from_user(kp, up, sizeof(*up)))
>  		return -EFAULT;
>  	return 0;
>  }
>  
>  static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
>  {
> -	if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
> +	if (copy_to_user(up, kp, sizeof(*up)))
>  		return -EFAULT;
>  	return 0;
>  }
> @@ -619,12 +616,11 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
>  	unsigned int n;
>  	compat_caddr_t p;
>  
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
> +	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
>  	    get_user(kp->which, &up->which) ||
>  	    get_user(kp->count, &up->count) ||
>  	    get_user(kp->error_idx, &up->error_idx) ||
> -	    copy_from_user(kp->reserved, up->reserved,
> -			   sizeof(kp->reserved)))
> +	    copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
>  		return -EFAULT;
>  	if (kp->count == 0) {
>  		kp->controls = NULL;
> @@ -635,11 +631,9 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
>  	if (get_user(p, &up->controls))
>  		return -EFAULT;
>  	ucontrols = compat_ptr(p);
> -	if (!access_ok(VERIFY_READ, ucontrols,
> -		       kp->count * sizeof(struct v4l2_ext_control32)))
> +	if (!access_ok(VERIFY_READ, ucontrols, kp->count * sizeof(*ucontrols)))
>  		return -EFAULT;
> -	kcontrols = compat_alloc_user_space(kp->count *
> -					    sizeof(struct v4l2_ext_control));
> +	kcontrols = compat_alloc_user_space(kp->count * sizeof(*kcontrols));
>  	kp->controls = (__force struct v4l2_ext_control *)kcontrols;
>  	for (n = 0; n < kp->count; n++) {
>  		u32 id;
> @@ -671,7 +665,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
>  	int n = kp->count;
>  	compat_caddr_t p;
>  
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
> +	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
>  	    put_user(kp->which, &up->which) ||
>  	    put_user(kp->count, &up->count) ||
>  	    put_user(kp->error_idx, &up->error_idx) ||
> @@ -683,8 +677,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
>  	if (get_user(p, &up->controls))
>  		return -EFAULT;
>  	ucontrols = compat_ptr(p);
> -	if (!access_ok(VERIFY_WRITE, ucontrols,
> -		       n * sizeof(struct v4l2_ext_control32)))
> +	if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(*ucontrols)))
>  		return -EFAULT;
>  
>  	while (--n >= 0) {
> @@ -721,7 +714,7 @@ struct v4l2_event32 {
>  
>  static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
>  {
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
> +	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) ||
> @@ -729,7 +722,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
>  	    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, 8 * sizeof(__u32)))
> +	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
>  		return -EFAULT;
>  	return 0;
>  }
> @@ -746,7 +739,7 @@ static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
>  {
>  	u32 tmp;
>  
> -	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
> +	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) ||
> @@ -761,7 +754,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
>  {
>  	u32 tmp = (u32)((unsigned long)kp->edid);
>  
> -	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
> +	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) ||
> -- 
> 2.15.1
> 

-- 
Sakari Ailus
e-mail: sakari.ailus@xxxxxx



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux