GNU Linux-libre 4.19.207-gnu1
[releases.git] / drivers / media / v4l2-core / v4l2-compat-ioctl32.c
1 /*
2  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3  *      Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
4  *
5  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
6  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
7  * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs
8  * Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
9  * Copyright (C) 2005       Philippe De Muyter (phdm@macqel.be)
10  * Copyright (C) 2008       Hans Verkuil <hverkuil@xs4all.nl>
11  *
12  * These routines maintain argument size conversion between 32bit and 64bit
13  * ioctls.
14  */
15
16 #include <linux/compat.h>
17 #include <linux/module.h>
18 #include <linux/videodev2.h>
19 #include <linux/v4l2-subdev.h>
20 #include <media/v4l2-dev.h>
21 #include <media/v4l2-fh.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-ioctl.h>
24
25 /**
26  * assign_in_user() - Copy from one __user var to another one
27  *
28  * @to: __user var where data will be stored
29  * @from: __user var where data will be retrieved.
30  *
31  * As this code very often needs to allocate userspace memory, it is easier
32  * to have a macro that will do both get_user() and put_user() at once.
33  *
34  * This function complements the macros defined at asm-generic/uaccess.h.
35  * It uses the same argument order as copy_in_user()
36  */
37 #define assign_in_user(to, from)                                        \
38 ({                                                                      \
39         typeof(*from) __assign_tmp;                                     \
40                                                                         \
41         get_user(__assign_tmp, from) || put_user(__assign_tmp, to);     \
42 })
43
44 /**
45  * get_user_cast() - Stores at a kernelspace local var the contents from a
46  *              pointer with userspace data that is not tagged with __user.
47  *
48  * @__x: var where data will be stored
49  * @__ptr: var where data will be retrieved.
50  *
51  * Sometimes we need to declare a pointer without __user because it
52  * comes from a pointer struct field that will be retrieved from userspace
53  * by the 64-bit native ioctl handler. This function ensures that the
54  * @__ptr will be cast to __user before calling get_user() in order to
55  * avoid warnings with static code analyzers like smatch.
56  */
57 #define get_user_cast(__x, __ptr)                                       \
58 ({                                                                      \
59         get_user(__x, (typeof(*__ptr) __user *)(__ptr));                \
60 })
61
62 /**
63  * put_user_force() - Stores the contents of a kernelspace local var
64  *                    into a userspace pointer, removing any __user cast.
65  *
66  * @__x: var where data will be stored
67  * @__ptr: var where data will be retrieved.
68  *
69  * Sometimes we need to remove the __user attribute from some data,
70  * by passing the __force macro. This function ensures that the
71  * @__ptr will be cast with __force before calling put_user(), in order to
72  * avoid warnings with static code analyzers like smatch.
73  */
74 #define put_user_force(__x, __ptr)                                      \
75 ({                                                                      \
76         put_user((typeof(*__x) __force *)(__x), __ptr);                 \
77 })
78
79 /**
80  * assign_in_user_cast() - Copy from one __user var to another one
81  *
82  * @to: __user var where data will be stored
83  * @from: var where data will be retrieved that needs to be cast to __user.
84  *
85  * As this code very often needs to allocate userspace memory, it is easier
86  * to have a macro that will do both get_user_cast() and put_user() at once.
87  *
88  * This function should be used instead of assign_in_user() when the @from
89  * variable was not declared as __user. See get_user_cast() for more details.
90  *
91  * This function complements the macros defined at asm-generic/uaccess.h.
92  * It uses the same argument order as copy_in_user()
93  */
94 #define assign_in_user_cast(to, from)                                   \
95 ({                                                                      \
96         typeof(*from) __assign_tmp;                                     \
97                                                                         \
98         get_user_cast(__assign_tmp, from) || put_user(__assign_tmp, to);\
99 })
100
101 /**
102  * native_ioctl - Ancillary function that calls the native 64 bits ioctl
103  * handler.
104  *
105  * @file: pointer to &struct file with the file handler
106  * @cmd: ioctl to be called
107  * @arg: arguments passed from/to the ioctl handler
108  *
109  * This function calls the native ioctl handler at v4l2-dev, e. g. v4l2_ioctl()
110  */
111 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
112 {
113         long ret = -ENOIOCTLCMD;
114
115         if (file->f_op->unlocked_ioctl)
116                 ret = file->f_op->unlocked_ioctl(file, cmd, arg);
117
118         return ret;
119 }
120
121
122 /*
123  * Per-ioctl data copy handlers.
124  *
125  * Those come in pairs, with a get_v4l2_foo() and a put_v4l2_foo() routine,
126  * where "v4l2_foo" is the name of the V4L2 struct.
127  *
128  * They basically get two __user pointers, one with a 32-bits struct that
129  * came from the userspace call and a 64-bits struct, also allocated as
130  * userspace, but filled internally by do_video_ioctl().
131  *
132  * For ioctls that have pointers inside it, the functions will also
133  * receive an ancillary buffer with extra space, used to pass extra
134  * data to the routine.
135  */
136
137 struct v4l2_clip32 {
138         struct v4l2_rect        c;
139         compat_caddr_t          next;
140 };
141
142 struct v4l2_window32 {
143         struct v4l2_rect        w;
144         __u32                   field;  /* enum v4l2_field */
145         __u32                   chromakey;
146         compat_caddr_t          clips; /* actually struct v4l2_clip32 * */
147         __u32                   clipcount;
148         compat_caddr_t          bitmap;
149         __u8                    global_alpha;
150 };
151
152 static int get_v4l2_window32(struct v4l2_window __user *p64,
153                              struct v4l2_window32 __user *p32,
154                              void __user *aux_buf, u32 aux_space)
155 {
156         struct v4l2_clip32 __user *uclips;
157         struct v4l2_clip __user *kclips;
158         compat_caddr_t p;
159         u32 clipcount;
160
161         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
162             copy_in_user(&p64->w, &p32->w, sizeof(p32->w)) ||
163             assign_in_user(&p64->field, &p32->field) ||
164             assign_in_user(&p64->chromakey, &p32->chromakey) ||
165             assign_in_user(&p64->global_alpha, &p32->global_alpha) ||
166             get_user(clipcount, &p32->clipcount) ||
167             put_user(clipcount, &p64->clipcount))
168                 return -EFAULT;
169         if (clipcount > 2048)
170                 return -EINVAL;
171         if (!clipcount)
172                 return put_user(NULL, &p64->clips);
173
174         if (get_user(p, &p32->clips))
175                 return -EFAULT;
176         uclips = compat_ptr(p);
177         if (aux_space < clipcount * sizeof(*kclips))
178                 return -EFAULT;
179         kclips = aux_buf;
180         if (put_user(kclips, &p64->clips))
181                 return -EFAULT;
182
183         while (clipcount--) {
184                 if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
185                         return -EFAULT;
186                 if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
187                         return -EFAULT;
188                 uclips++;
189                 kclips++;
190         }
191         return 0;
192 }
193
194 static int put_v4l2_window32(struct v4l2_window __user *p64,
195                              struct v4l2_window32 __user *p32)
196 {
197         struct v4l2_clip __user *kclips;
198         struct v4l2_clip32 __user *uclips;
199         compat_caddr_t p;
200         u32 clipcount;
201
202         if (copy_in_user(&p32->w, &p64->w, sizeof(p64->w)) ||
203             assign_in_user(&p32->field, &p64->field) ||
204             assign_in_user(&p32->chromakey, &p64->chromakey) ||
205             assign_in_user(&p32->global_alpha, &p64->global_alpha) ||
206             get_user(clipcount, &p64->clipcount) ||
207             put_user(clipcount, &p32->clipcount))
208                 return -EFAULT;
209         if (!clipcount)
210                 return 0;
211
212         if (get_user(kclips, &p64->clips))
213                 return -EFAULT;
214         if (get_user(p, &p32->clips))
215                 return -EFAULT;
216         uclips = compat_ptr(p);
217         while (clipcount--) {
218                 if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
219                         return -EFAULT;
220                 uclips++;
221                 kclips++;
222         }
223         return 0;
224 }
225
226 struct v4l2_format32 {
227         __u32   type;   /* enum v4l2_buf_type */
228         union {
229                 struct v4l2_pix_format  pix;
230                 struct v4l2_pix_format_mplane   pix_mp;
231                 struct v4l2_window32    win;
232                 struct v4l2_vbi_format  vbi;
233                 struct v4l2_sliced_vbi_format   sliced;
234                 struct v4l2_sdr_format  sdr;
235                 struct v4l2_meta_format meta;
236                 __u8    raw_data[200];        /* user-defined */
237         } fmt;
238 };
239
240 /**
241  * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
242  * @index:      on return, index of the first created buffer
243  * @count:      entry: number of requested buffers,
244  *              return: number of created buffers
245  * @memory:     buffer memory type
246  * @format:     frame format, for which buffers are requested
247  * @reserved:   future extensions
248  */
249 struct v4l2_create_buffers32 {
250         __u32                   index;
251         __u32                   count;
252         __u32                   memory; /* enum v4l2_memory */
253         struct v4l2_format32    format;
254         __u32                   reserved[8];
255 };
256
257 static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
258 {
259         u32 type;
260
261         if (get_user(type, &p32->type))
262                 return -EFAULT;
263
264         switch (type) {
265         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
266         case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
267                 u32 clipcount;
268
269                 if (get_user(clipcount, &p32->fmt.win.clipcount))
270                         return -EFAULT;
271                 if (clipcount > 2048)
272                         return -EINVAL;
273                 *size = clipcount * sizeof(struct v4l2_clip);
274                 return 0;
275         }
276         default:
277                 *size = 0;
278                 return 0;
279         }
280 }
281
282 static int bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
283 {
284         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
285                 return -EFAULT;
286         return __bufsize_v4l2_format(p32, size);
287 }
288
289 static int __get_v4l2_format32(struct v4l2_format __user *p64,
290                                struct v4l2_format32 __user *p32,
291                                void __user *aux_buf, u32 aux_space)
292 {
293         u32 type;
294
295         if (get_user(type, &p32->type) || put_user(type, &p64->type))
296                 return -EFAULT;
297
298         switch (type) {
299         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
300         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
301                 return copy_in_user(&p64->fmt.pix, &p32->fmt.pix,
302                                     sizeof(p64->fmt.pix)) ? -EFAULT : 0;
303         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
304         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
305                 return copy_in_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
306                                     sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
307         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
308         case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
309                 return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win,
310                                          aux_buf, aux_space);
311         case V4L2_BUF_TYPE_VBI_CAPTURE:
312         case V4L2_BUF_TYPE_VBI_OUTPUT:
313                 return copy_in_user(&p64->fmt.vbi, &p32->fmt.vbi,
314                                     sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
315         case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
316         case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
317                 return copy_in_user(&p64->fmt.sliced, &p32->fmt.sliced,
318                                     sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
319         case V4L2_BUF_TYPE_SDR_CAPTURE:
320         case V4L2_BUF_TYPE_SDR_OUTPUT:
321                 return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
322                                     sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
323         case V4L2_BUF_TYPE_META_CAPTURE:
324                 return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
325                                     sizeof(p64->fmt.meta)) ? -EFAULT : 0;
326         default:
327                 return -EINVAL;
328         }
329 }
330
331 static int get_v4l2_format32(struct v4l2_format __user *p64,
332                              struct v4l2_format32 __user *p32,
333                              void __user *aux_buf, u32 aux_space)
334 {
335         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
336                 return -EFAULT;
337         return __get_v4l2_format32(p64, p32, aux_buf, aux_space);
338 }
339
340 static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *p32,
341                                u32 *size)
342 {
343         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)))
344                 return -EFAULT;
345         return __bufsize_v4l2_format(&p32->format, size);
346 }
347
348 static int get_v4l2_create32(struct v4l2_create_buffers __user *p64,
349                              struct v4l2_create_buffers32 __user *p32,
350                              void __user *aux_buf, u32 aux_space)
351 {
352         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
353             copy_in_user(p64, p32,
354                          offsetof(struct v4l2_create_buffers32, format)))
355                 return -EFAULT;
356         return __get_v4l2_format32(&p64->format, &p32->format,
357                                    aux_buf, aux_space);
358 }
359
360 static int __put_v4l2_format32(struct v4l2_format __user *p64,
361                                struct v4l2_format32 __user *p32)
362 {
363         u32 type;
364
365         if (get_user(type, &p64->type))
366                 return -EFAULT;
367
368         switch (type) {
369         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
370         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
371                 return copy_in_user(&p32->fmt.pix, &p64->fmt.pix,
372                                     sizeof(p64->fmt.pix)) ? -EFAULT : 0;
373         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
374         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
375                 return copy_in_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
376                                     sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
377         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
378         case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
379                 return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
380         case V4L2_BUF_TYPE_VBI_CAPTURE:
381         case V4L2_BUF_TYPE_VBI_OUTPUT:
382                 return copy_in_user(&p32->fmt.vbi, &p64->fmt.vbi,
383                                     sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
384         case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
385         case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
386                 return copy_in_user(&p32->fmt.sliced, &p64->fmt.sliced,
387                                     sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
388         case V4L2_BUF_TYPE_SDR_CAPTURE:
389         case V4L2_BUF_TYPE_SDR_OUTPUT:
390                 return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
391                                     sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
392         case V4L2_BUF_TYPE_META_CAPTURE:
393                 return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
394                                     sizeof(p64->fmt.meta)) ? -EFAULT : 0;
395         default:
396                 return -EINVAL;
397         }
398 }
399
400 static int put_v4l2_format32(struct v4l2_format __user *p64,
401                              struct v4l2_format32 __user *p32)
402 {
403         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)))
404                 return -EFAULT;
405         return __put_v4l2_format32(p64, p32);
406 }
407
408 static int put_v4l2_create32(struct v4l2_create_buffers __user *p64,
409                              struct v4l2_create_buffers32 __user *p32)
410 {
411         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
412             copy_in_user(p32, p64,
413                          offsetof(struct v4l2_create_buffers32, format)) ||
414             copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
415                 return -EFAULT;
416         return __put_v4l2_format32(&p64->format, &p32->format);
417 }
418
419 struct v4l2_standard32 {
420         __u32                index;
421         compat_u64           id;
422         __u8                 name[24];
423         struct v4l2_fract    frameperiod; /* Frames, not fields */
424         __u32                framelines;
425         __u32                reserved[4];
426 };
427
428 static int get_v4l2_standard32(struct v4l2_standard __user *p64,
429                                struct v4l2_standard32 __user *p32)
430 {
431         /* other fields are not set by the user, nor used by the driver */
432         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
433             assign_in_user(&p64->index, &p32->index))
434                 return -EFAULT;
435         return 0;
436 }
437
438 static int put_v4l2_standard32(struct v4l2_standard __user *p64,
439                                struct v4l2_standard32 __user *p32)
440 {
441         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
442             assign_in_user(&p32->index, &p64->index) ||
443             assign_in_user(&p32->id, &p64->id) ||
444             copy_in_user(p32->name, p64->name, sizeof(p32->name)) ||
445             copy_in_user(&p32->frameperiod, &p64->frameperiod,
446                          sizeof(p32->frameperiod)) ||
447             assign_in_user(&p32->framelines, &p64->framelines) ||
448             copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
449                 return -EFAULT;
450         return 0;
451 }
452
453 struct v4l2_plane32 {
454         __u32                   bytesused;
455         __u32                   length;
456         union {
457                 __u32           mem_offset;
458                 compat_long_t   userptr;
459                 __s32           fd;
460         } m;
461         __u32                   data_offset;
462         __u32                   reserved[11];
463 };
464
465 struct v4l2_buffer32 {
466         __u32                   index;
467         __u32                   type;   /* enum v4l2_buf_type */
468         __u32                   bytesused;
469         __u32                   flags;
470         __u32                   field;  /* enum v4l2_field */
471         struct compat_timeval   timestamp;
472         struct v4l2_timecode    timecode;
473         __u32                   sequence;
474
475         /* memory location */
476         __u32                   memory; /* enum v4l2_memory */
477         union {
478                 __u32           offset;
479                 compat_long_t   userptr;
480                 compat_caddr_t  planes;
481                 __s32           fd;
482         } m;
483         __u32                   length;
484         __u32                   reserved2;
485         __u32                   reserved;
486 };
487
488 static int get_v4l2_plane32(struct v4l2_plane __user *p64,
489                             struct v4l2_plane32 __user *p32,
490                             enum v4l2_memory memory)
491 {
492         compat_ulong_t p;
493
494         if (copy_in_user(p64, p32, 2 * sizeof(__u32)) ||
495             copy_in_user(&p64->data_offset, &p32->data_offset,
496                          sizeof(p64->data_offset)))
497                 return -EFAULT;
498
499         switch (memory) {
500         case V4L2_MEMORY_MMAP:
501         case V4L2_MEMORY_OVERLAY:
502                 if (copy_in_user(&p64->m.mem_offset, &p32->m.mem_offset,
503                                  sizeof(p32->m.mem_offset)))
504                         return -EFAULT;
505                 break;
506         case V4L2_MEMORY_USERPTR:
507                 if (get_user(p, &p32->m.userptr) ||
508                     put_user((unsigned long)compat_ptr(p), &p64->m.userptr))
509                         return -EFAULT;
510                 break;
511         case V4L2_MEMORY_DMABUF:
512                 if (copy_in_user(&p64->m.fd, &p32->m.fd, sizeof(p32->m.fd)))
513                         return -EFAULT;
514                 break;
515         }
516
517         return 0;
518 }
519
520 static int put_v4l2_plane32(struct v4l2_plane __user *p64,
521                             struct v4l2_plane32 __user *p32,
522                             enum v4l2_memory memory)
523 {
524         unsigned long p;
525
526         if (copy_in_user(p32, p64, 2 * sizeof(__u32)) ||
527             copy_in_user(&p32->data_offset, &p64->data_offset,
528                          sizeof(p64->data_offset)))
529                 return -EFAULT;
530
531         switch (memory) {
532         case V4L2_MEMORY_MMAP:
533         case V4L2_MEMORY_OVERLAY:
534                 if (copy_in_user(&p32->m.mem_offset, &p64->m.mem_offset,
535                                  sizeof(p64->m.mem_offset)))
536                         return -EFAULT;
537                 break;
538         case V4L2_MEMORY_USERPTR:
539                 if (get_user(p, &p64->m.userptr) ||
540                     put_user((compat_ulong_t)ptr_to_compat((void __user *)p),
541                              &p32->m.userptr))
542                         return -EFAULT;
543                 break;
544         case V4L2_MEMORY_DMABUF:
545                 if (copy_in_user(&p32->m.fd, &p64->m.fd, sizeof(p64->m.fd)))
546                         return -EFAULT;
547                 break;
548         }
549
550         return 0;
551 }
552
553 static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *p32, u32 *size)
554 {
555         u32 type;
556         u32 length;
557
558         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
559             get_user(type, &p32->type) ||
560             get_user(length, &p32->length))
561                 return -EFAULT;
562
563         if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
564                 if (length > VIDEO_MAX_PLANES)
565                         return -EINVAL;
566
567                 /*
568                  * We don't really care if userspace decides to kill itself
569                  * by passing a very big length value
570                  */
571                 *size = length * sizeof(struct v4l2_plane);
572         } else {
573                 *size = 0;
574         }
575         return 0;
576 }
577
578 static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
579                              struct v4l2_buffer32 __user *p32,
580                              void __user *aux_buf, u32 aux_space)
581 {
582         u32 type;
583         u32 length;
584         enum v4l2_memory memory;
585         struct v4l2_plane32 __user *uplane32;
586         struct v4l2_plane __user *uplane;
587         compat_caddr_t p;
588         int ret;
589
590         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
591             assign_in_user(&p64->index, &p32->index) ||
592             get_user(type, &p32->type) ||
593             put_user(type, &p64->type) ||
594             assign_in_user(&p64->flags, &p32->flags) ||
595             get_user(memory, &p32->memory) ||
596             put_user(memory, &p64->memory) ||
597             get_user(length, &p32->length) ||
598             put_user(length, &p64->length))
599                 return -EFAULT;
600
601         if (V4L2_TYPE_IS_OUTPUT(type))
602                 if (assign_in_user(&p64->bytesused, &p32->bytesused) ||
603                     assign_in_user(&p64->field, &p32->field) ||
604                     assign_in_user(&p64->timestamp.tv_sec,
605                                    &p32->timestamp.tv_sec) ||
606                     assign_in_user(&p64->timestamp.tv_usec,
607                                    &p32->timestamp.tv_usec))
608                         return -EFAULT;
609
610         if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
611                 u32 num_planes = length;
612
613                 if (num_planes == 0) {
614                         /*
615                          * num_planes == 0 is legal, e.g. when userspace doesn't
616                          * need planes array on DQBUF
617                          */
618                         return put_user(NULL, &p64->m.planes);
619                 }
620                 if (num_planes > VIDEO_MAX_PLANES)
621                         return -EINVAL;
622
623                 if (get_user(p, &p32->m.planes))
624                         return -EFAULT;
625
626                 uplane32 = compat_ptr(p);
627                 if (!access_ok(VERIFY_READ, uplane32,
628                                num_planes * sizeof(*uplane32)))
629                         return -EFAULT;
630
631                 /*
632                  * We don't really care if userspace decides to kill itself
633                  * by passing a very big num_planes value
634                  */
635                 if (aux_space < num_planes * sizeof(*uplane))
636                         return -EFAULT;
637
638                 uplane = aux_buf;
639                 if (put_user_force(uplane, &p64->m.planes))
640                         return -EFAULT;
641
642                 while (num_planes--) {
643                         ret = get_v4l2_plane32(uplane, uplane32, memory);
644                         if (ret)
645                                 return ret;
646                         uplane++;
647                         uplane32++;
648                 }
649         } else {
650                 switch (memory) {
651                 case V4L2_MEMORY_MMAP:
652                 case V4L2_MEMORY_OVERLAY:
653                         if (assign_in_user(&p64->m.offset, &p32->m.offset))
654                                 return -EFAULT;
655                         break;
656                 case V4L2_MEMORY_USERPTR: {
657                         compat_ulong_t userptr;
658
659                         if (get_user(userptr, &p32->m.userptr) ||
660                             put_user((unsigned long)compat_ptr(userptr),
661                                      &p64->m.userptr))
662                                 return -EFAULT;
663                         break;
664                 }
665                 case V4L2_MEMORY_DMABUF:
666                         if (assign_in_user(&p64->m.fd, &p32->m.fd))
667                                 return -EFAULT;
668                         break;
669                 }
670         }
671
672         return 0;
673 }
674
675 static int put_v4l2_buffer32(struct v4l2_buffer __user *p64,
676                              struct v4l2_buffer32 __user *p32)
677 {
678         u32 type;
679         u32 length;
680         enum v4l2_memory memory;
681         struct v4l2_plane32 __user *uplane32;
682         struct v4l2_plane *uplane;
683         compat_caddr_t p;
684         int ret;
685
686         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
687             assign_in_user(&p32->index, &p64->index) ||
688             get_user(type, &p64->type) ||
689             put_user(type, &p32->type) ||
690             assign_in_user(&p32->flags, &p64->flags) ||
691             get_user(memory, &p64->memory) ||
692             put_user(memory, &p32->memory))
693                 return -EFAULT;
694
695         if (assign_in_user(&p32->bytesused, &p64->bytesused) ||
696             assign_in_user(&p32->field, &p64->field) ||
697             assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
698             assign_in_user(&p32->timestamp.tv_usec, &p64->timestamp.tv_usec) ||
699             copy_in_user(&p32->timecode, &p64->timecode, sizeof(p64->timecode)) ||
700             assign_in_user(&p32->sequence, &p64->sequence) ||
701             assign_in_user(&p32->reserved2, &p64->reserved2) ||
702             assign_in_user(&p32->reserved, &p64->reserved) ||
703             get_user(length, &p64->length) ||
704             put_user(length, &p32->length))
705                 return -EFAULT;
706
707         if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
708                 u32 num_planes = length;
709
710                 if (num_planes == 0)
711                         return 0;
712                 /* We need to define uplane without __user, even though
713                  * it does point to data in userspace here. The reason is
714                  * that v4l2-ioctl.c copies it from userspace to kernelspace,
715                  * so its definition in videodev2.h doesn't have a
716                  * __user markup. Defining uplane with __user causes
717                  * smatch warnings, so instead declare it without __user
718                  * and cast it as a userspace pointer to put_v4l2_plane32().
719                  */
720                 if (get_user(uplane, &p64->m.planes))
721                         return -EFAULT;
722                 if (get_user(p, &p32->m.planes))
723                         return -EFAULT;
724                 uplane32 = compat_ptr(p);
725
726                 while (num_planes--) {
727                         ret = put_v4l2_plane32((void __user *)uplane,
728                                                uplane32, memory);
729                         if (ret)
730                                 return ret;
731                         ++uplane;
732                         ++uplane32;
733                 }
734         } else {
735                 switch (memory) {
736                 case V4L2_MEMORY_MMAP:
737                 case V4L2_MEMORY_OVERLAY:
738                         if (assign_in_user(&p32->m.offset, &p64->m.offset))
739                                 return -EFAULT;
740                         break;
741                 case V4L2_MEMORY_USERPTR:
742                         if (assign_in_user(&p32->m.userptr, &p64->m.userptr))
743                                 return -EFAULT;
744                         break;
745                 case V4L2_MEMORY_DMABUF:
746                         if (assign_in_user(&p32->m.fd, &p64->m.fd))
747                                 return -EFAULT;
748                         break;
749                 }
750         }
751
752         return 0;
753 }
754
755 struct v4l2_framebuffer32 {
756         __u32                   capability;
757         __u32                   flags;
758         compat_caddr_t          base;
759         struct {
760                 __u32           width;
761                 __u32           height;
762                 __u32           pixelformat;
763                 __u32           field;
764                 __u32           bytesperline;
765                 __u32           sizeimage;
766                 __u32           colorspace;
767                 __u32           priv;
768         } fmt;
769 };
770
771 static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
772                                   struct v4l2_framebuffer32 __user *p32)
773 {
774         compat_caddr_t tmp;
775
776         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
777             get_user(tmp, &p32->base) ||
778             put_user_force(compat_ptr(tmp), &p64->base) ||
779             assign_in_user(&p64->capability, &p32->capability) ||
780             assign_in_user(&p64->flags, &p32->flags) ||
781             copy_in_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
782                 return -EFAULT;
783         return 0;
784 }
785
786 static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
787                                   struct v4l2_framebuffer32 __user *p32)
788 {
789         void *base;
790
791         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
792             get_user(base, &p64->base) ||
793             put_user(ptr_to_compat((void __user *)base), &p32->base) ||
794             assign_in_user(&p32->capability, &p64->capability) ||
795             assign_in_user(&p32->flags, &p64->flags) ||
796             copy_in_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
797                 return -EFAULT;
798         return 0;
799 }
800
801 struct v4l2_input32 {
802         __u32        index;             /*  Which input */
803         __u8         name[32];          /*  Label */
804         __u32        type;              /*  Type of input */
805         __u32        audioset;          /*  Associated audios (bitfield) */
806         __u32        tuner;             /*  Associated tuner */
807         compat_u64   std;
808         __u32        status;
809         __u32        capabilities;
810         __u32        reserved[3];
811 };
812
813 /*
814  * The 64-bit v4l2_input struct has extra padding at the end of the struct.
815  * Otherwise it is identical to the 32-bit version.
816  */
817 static inline int get_v4l2_input32(struct v4l2_input __user *p64,
818                                    struct v4l2_input32 __user *p32)
819 {
820         if (copy_in_user(p64, p32, sizeof(*p32)))
821                 return -EFAULT;
822         return 0;
823 }
824
825 static inline int put_v4l2_input32(struct v4l2_input __user *p64,
826                                    struct v4l2_input32 __user *p32)
827 {
828         if (copy_in_user(p32, p64, sizeof(*p32)))
829                 return -EFAULT;
830         return 0;
831 }
832
833 struct v4l2_ext_controls32 {
834         __u32 which;
835         __u32 count;
836         __u32 error_idx;
837         __u32 reserved[2];
838         compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
839 };
840
841 struct v4l2_ext_control32 {
842         __u32 id;
843         __u32 size;
844         __u32 reserved2[1];
845         union {
846                 __s32 value;
847                 __s64 value64;
848                 compat_caddr_t string; /* actually char * */
849         };
850 } __attribute__ ((packed));
851
852 /* Return true if this control is a pointer type. */
853 static inline bool ctrl_is_pointer(struct file *file, u32 id)
854 {
855         struct video_device *vdev = video_devdata(file);
856         struct v4l2_fh *fh = NULL;
857         struct v4l2_ctrl_handler *hdl = NULL;
858         struct v4l2_query_ext_ctrl qec = { id };
859         const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
860
861         if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
862                 fh = file->private_data;
863
864         if (fh && fh->ctrl_handler)
865                 hdl = fh->ctrl_handler;
866         else if (vdev->ctrl_handler)
867                 hdl = vdev->ctrl_handler;
868
869         if (hdl) {
870                 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
871
872                 return ctrl && ctrl->is_ptr;
873         }
874
875         if (!ops || !ops->vidioc_query_ext_ctrl)
876                 return false;
877
878         return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
879                 (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
880 }
881
882 static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *p32,
883                                      u32 *size)
884 {
885         u32 count;
886
887         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
888             get_user(count, &p32->count))
889                 return -EFAULT;
890         if (count > V4L2_CID_MAX_CTRLS)
891                 return -EINVAL;
892         *size = count * sizeof(struct v4l2_ext_control);
893         return 0;
894 }
895
896 static int get_v4l2_ext_controls32(struct file *file,
897                                    struct v4l2_ext_controls __user *p64,
898                                    struct v4l2_ext_controls32 __user *p32,
899                                    void __user *aux_buf, u32 aux_space)
900 {
901         struct v4l2_ext_control32 __user *ucontrols;
902         struct v4l2_ext_control __user *kcontrols;
903         u32 count;
904         u32 n;
905         compat_caddr_t p;
906
907         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
908             assign_in_user(&p64->which, &p32->which) ||
909             get_user(count, &p32->count) ||
910             put_user(count, &p64->count) ||
911             assign_in_user(&p64->error_idx, &p32->error_idx) ||
912             copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
913                 return -EFAULT;
914
915         if (count == 0)
916                 return put_user(NULL, &p64->controls);
917         if (count > V4L2_CID_MAX_CTRLS)
918                 return -EINVAL;
919         if (get_user(p, &p32->controls))
920                 return -EFAULT;
921         ucontrols = compat_ptr(p);
922         if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
923                 return -EFAULT;
924         if (aux_space < count * sizeof(*kcontrols))
925                 return -EFAULT;
926         kcontrols = aux_buf;
927         if (put_user_force(kcontrols, &p64->controls))
928                 return -EFAULT;
929
930         for (n = 0; n < count; n++) {
931                 u32 id;
932
933                 if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
934                         return -EFAULT;
935
936                 if (get_user(id, &kcontrols->id))
937                         return -EFAULT;
938
939                 if (ctrl_is_pointer(file, id)) {
940                         void __user *s;
941
942                         if (get_user(p, &ucontrols->string))
943                                 return -EFAULT;
944                         s = compat_ptr(p);
945                         if (put_user(s, &kcontrols->string))
946                                 return -EFAULT;
947                 }
948                 ucontrols++;
949                 kcontrols++;
950         }
951         return 0;
952 }
953
954 static int put_v4l2_ext_controls32(struct file *file,
955                                    struct v4l2_ext_controls __user *p64,
956                                    struct v4l2_ext_controls32 __user *p32)
957 {
958         struct v4l2_ext_control32 __user *ucontrols;
959         struct v4l2_ext_control *kcontrols;
960         u32 count;
961         u32 n;
962         compat_caddr_t p;
963
964         /*
965          * We need to define kcontrols without __user, even though it does
966          * point to data in userspace here. The reason is that v4l2-ioctl.c
967          * copies it from userspace to kernelspace, so its definition in
968          * videodev2.h doesn't have a __user markup. Defining kcontrols
969          * with __user causes smatch warnings, so instead declare it
970          * without __user and cast it as a userspace pointer where needed.
971          */
972         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
973             assign_in_user(&p32->which, &p64->which) ||
974             get_user(count, &p64->count) ||
975             put_user(count, &p32->count) ||
976             assign_in_user(&p32->error_idx, &p64->error_idx) ||
977             copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)) ||
978             get_user(kcontrols, &p64->controls))
979                 return -EFAULT;
980
981         if (!count || count > (U32_MAX/sizeof(*ucontrols)))
982                 return 0;
983         if (get_user(p, &p32->controls))
984                 return -EFAULT;
985         ucontrols = compat_ptr(p);
986         if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
987                 return -EFAULT;
988
989         for (n = 0; n < count; n++) {
990                 unsigned int size = sizeof(*ucontrols);
991                 u32 id;
992
993                 if (get_user_cast(id, &kcontrols->id) ||
994                     put_user(id, &ucontrols->id) ||
995                     assign_in_user_cast(&ucontrols->size, &kcontrols->size) ||
996                     copy_in_user(&ucontrols->reserved2,
997                                  (void __user *)&kcontrols->reserved2,
998                                  sizeof(ucontrols->reserved2)))
999                         return -EFAULT;
1000
1001                 /*
1002                  * Do not modify the pointer when copying a pointer control.
1003                  * The contents of the pointer was changed, not the pointer
1004                  * itself.
1005                  */
1006                 if (ctrl_is_pointer(file, id))
1007                         size -= sizeof(ucontrols->value64);
1008
1009                 if (copy_in_user(ucontrols,
1010                                  (void __user *)kcontrols, size))
1011                         return -EFAULT;
1012
1013                 ucontrols++;
1014                 kcontrols++;
1015         }
1016         return 0;
1017 }
1018
1019 struct v4l2_event32 {
1020         __u32                           type;
1021         union {
1022                 compat_s64              value64;
1023                 __u8                    data[64];
1024         } u;
1025         __u32                           pending;
1026         __u32                           sequence;
1027         struct compat_timespec          timestamp;
1028         __u32                           id;
1029         __u32                           reserved[8];
1030 };
1031
1032 static int put_v4l2_event32(struct v4l2_event __user *p64,
1033                             struct v4l2_event32 __user *p32)
1034 {
1035         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
1036             assign_in_user(&p32->type, &p64->type) ||
1037             copy_in_user(&p32->u, &p64->u, sizeof(p64->u)) ||
1038             assign_in_user(&p32->pending, &p64->pending) ||
1039             assign_in_user(&p32->sequence, &p64->sequence) ||
1040             assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
1041             assign_in_user(&p32->timestamp.tv_nsec, &p64->timestamp.tv_nsec) ||
1042             assign_in_user(&p32->id, &p64->id) ||
1043             copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
1044                 return -EFAULT;
1045         return 0;
1046 }
1047
1048 struct v4l2_edid32 {
1049         __u32 pad;
1050         __u32 start_block;
1051         __u32 blocks;
1052         __u32 reserved[5];
1053         compat_caddr_t edid;
1054 };
1055
1056 static int get_v4l2_edid32(struct v4l2_edid __user *p64,
1057                            struct v4l2_edid32 __user *p32)
1058 {
1059         compat_uptr_t tmp;
1060
1061         if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
1062             assign_in_user(&p64->pad, &p32->pad) ||
1063             assign_in_user(&p64->start_block, &p32->start_block) ||
1064             assign_in_user_cast(&p64->blocks, &p32->blocks) ||
1065             get_user(tmp, &p32->edid) ||
1066             put_user_force(compat_ptr(tmp), &p64->edid) ||
1067             copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
1068                 return -EFAULT;
1069         return 0;
1070 }
1071
1072 static int put_v4l2_edid32(struct v4l2_edid __user *p64,
1073                            struct v4l2_edid32 __user *p32)
1074 {
1075         void *edid;
1076
1077         if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
1078             assign_in_user(&p32->pad, &p64->pad) ||
1079             assign_in_user(&p32->start_block, &p64->start_block) ||
1080             assign_in_user(&p32->blocks, &p64->blocks) ||
1081             get_user(edid, &p64->edid) ||
1082             put_user(ptr_to_compat((void __user *)edid), &p32->edid) ||
1083             copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
1084                 return -EFAULT;
1085         return 0;
1086 }
1087
1088 /*
1089  * List of ioctls that require 32-bits/64-bits conversion
1090  *
1091  * The V4L2 ioctls that aren't listed there don't have pointer arguments
1092  * and the struct size is identical for both 32 and 64 bits versions, so
1093  * they don't need translations.
1094  */
1095
1096 #define VIDIOC_G_FMT32          _IOWR('V',  4, struct v4l2_format32)
1097 #define VIDIOC_S_FMT32          _IOWR('V',  5, struct v4l2_format32)
1098 #define VIDIOC_QUERYBUF32       _IOWR('V',  9, struct v4l2_buffer32)
1099 #define VIDIOC_G_FBUF32         _IOR ('V', 10, struct v4l2_framebuffer32)
1100 #define VIDIOC_S_FBUF32         _IOW ('V', 11, struct v4l2_framebuffer32)
1101 #define VIDIOC_QBUF32           _IOWR('V', 15, struct v4l2_buffer32)
1102 #define VIDIOC_DQBUF32          _IOWR('V', 17, struct v4l2_buffer32)
1103 #define VIDIOC_ENUMSTD32        _IOWR('V', 25, struct v4l2_standard32)
1104 #define VIDIOC_ENUMINPUT32      _IOWR('V', 26, struct v4l2_input32)
1105 #define VIDIOC_G_EDID32         _IOWR('V', 40, struct v4l2_edid32)
1106 #define VIDIOC_S_EDID32         _IOWR('V', 41, struct v4l2_edid32)
1107 #define VIDIOC_TRY_FMT32        _IOWR('V', 64, struct v4l2_format32)
1108 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
1109 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
1110 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
1111 #define VIDIOC_DQEVENT32        _IOR ('V', 89, struct v4l2_event32)
1112 #define VIDIOC_CREATE_BUFS32    _IOWR('V', 92, struct v4l2_create_buffers32)
1113 #define VIDIOC_PREPARE_BUF32    _IOWR('V', 93, struct v4l2_buffer32)
1114
1115 #define VIDIOC_OVERLAY32        _IOW ('V', 14, s32)
1116 #define VIDIOC_STREAMON32       _IOW ('V', 18, s32)
1117 #define VIDIOC_STREAMOFF32      _IOW ('V', 19, s32)
1118 #define VIDIOC_G_INPUT32        _IOR ('V', 38, s32)
1119 #define VIDIOC_S_INPUT32        _IOWR('V', 39, s32)
1120 #define VIDIOC_G_OUTPUT32       _IOR ('V', 46, s32)
1121 #define VIDIOC_S_OUTPUT32       _IOWR('V', 47, s32)
1122
1123 /**
1124  * alloc_userspace() - Allocates a 64-bits userspace pointer compatible
1125  *      for calling the native 64-bits version of an ioctl.
1126  *
1127  * @size:       size of the structure itself to be allocated.
1128  * @aux_space:  extra size needed to store "extra" data, e.g. space for
1129  *              other __user data that is pointed to fields inside the
1130  *              structure.
1131  * @new_p64:    pointer to a pointer to be filled with the allocated struct.
1132  *
1133  * Return:
1134  *
1135  * if it can't allocate memory, either -ENOMEM or -EFAULT will be returned.
1136  * Zero otherwise.
1137  */
1138 static int alloc_userspace(unsigned int size, u32 aux_space,
1139                            void __user **new_p64)
1140 {
1141         *new_p64 = compat_alloc_user_space(size + aux_space);
1142         if (!*new_p64)
1143                 return -ENOMEM;
1144         if (clear_user(*new_p64, size))
1145                 return -EFAULT;
1146         return 0;
1147 }
1148
1149 /**
1150  * do_video_ioctl() - Ancillary function with handles a compat32 ioctl call
1151  *
1152  * @file: pointer to &struct file with the file handler
1153  * @cmd: ioctl to be called
1154  * @arg: arguments passed from/to the ioctl handler
1155  *
1156  * This function is called when a 32 bits application calls a V4L2 ioctl
1157  * and the Kernel is compiled with 64 bits.
1158  *
1159  * This function is called by v4l2_compat_ioctl32() when the function is
1160  * not private to some specific driver.
1161  *
1162  * It converts a 32-bits struct into a 64 bits one, calls the native 64-bits
1163  * ioctl handler and fills back the 32-bits struct with the results of the
1164  * native call.
1165  */
1166 static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1167 {
1168         void __user *p32 = compat_ptr(arg);
1169         void __user *new_p64 = NULL;
1170         void __user *aux_buf;
1171         u32 aux_space;
1172         int compatible_arg = 1;
1173         long err = 0;
1174         unsigned int ncmd;
1175
1176         /*
1177          * 1. When struct size is different, converts the command.
1178          */
1179         switch (cmd) {
1180         case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break;
1181         case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break;
1182         case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break;
1183         case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break;
1184         case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break;
1185         case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break;
1186         case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break;
1187         case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break;
1188         case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break;
1189         case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break;
1190         case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
1191         case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
1192         case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
1193         case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
1194         case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
1195         case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
1196         case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
1197         case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break;
1198         case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break;
1199         case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break;
1200         case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break;
1201         case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break;
1202         case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break;
1203         case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break;
1204         case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break;
1205         default: ncmd = cmd; break;
1206         }
1207
1208         /*
1209          * 2. Allocates a 64-bits userspace pointer to store the
1210          * values of the ioctl and copy data from the 32-bits __user
1211          * argument into it.
1212          */
1213         switch (cmd) {
1214         case VIDIOC_OVERLAY32:
1215         case VIDIOC_STREAMON32:
1216         case VIDIOC_STREAMOFF32:
1217         case VIDIOC_S_INPUT32:
1218         case VIDIOC_S_OUTPUT32:
1219                 err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
1220                 if (!err && assign_in_user((unsigned int __user *)new_p64,
1221                                            (compat_uint_t __user *)p32))
1222                         err = -EFAULT;
1223                 compatible_arg = 0;
1224                 break;
1225
1226         case VIDIOC_G_INPUT32:
1227         case VIDIOC_G_OUTPUT32:
1228                 err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
1229                 compatible_arg = 0;
1230                 break;
1231
1232         case VIDIOC_G_EDID32:
1233         case VIDIOC_S_EDID32:
1234                 err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64);
1235                 if (!err)
1236                         err = get_v4l2_edid32(new_p64, p32);
1237                 compatible_arg = 0;
1238                 break;
1239
1240         case VIDIOC_G_FMT32:
1241         case VIDIOC_S_FMT32:
1242         case VIDIOC_TRY_FMT32:
1243                 err = bufsize_v4l2_format(p32, &aux_space);
1244                 if (!err)
1245                         err = alloc_userspace(sizeof(struct v4l2_format),
1246                                               aux_space, &new_p64);
1247                 if (!err) {
1248                         aux_buf = new_p64 + sizeof(struct v4l2_format);
1249                         err = get_v4l2_format32(new_p64, p32,
1250                                                 aux_buf, aux_space);
1251                 }
1252                 compatible_arg = 0;
1253                 break;
1254
1255         case VIDIOC_CREATE_BUFS32:
1256                 err = bufsize_v4l2_create(p32, &aux_space);
1257                 if (!err)
1258                         err = alloc_userspace(sizeof(struct v4l2_create_buffers),
1259                                               aux_space, &new_p64);
1260                 if (!err) {
1261                         aux_buf = new_p64 + sizeof(struct v4l2_create_buffers);
1262                         err = get_v4l2_create32(new_p64, p32,
1263                                                 aux_buf, aux_space);
1264                 }
1265                 compatible_arg = 0;
1266                 break;
1267
1268         case VIDIOC_PREPARE_BUF32:
1269         case VIDIOC_QUERYBUF32:
1270         case VIDIOC_QBUF32:
1271         case VIDIOC_DQBUF32:
1272                 err = bufsize_v4l2_buffer(p32, &aux_space);
1273                 if (!err)
1274                         err = alloc_userspace(sizeof(struct v4l2_buffer),
1275                                               aux_space, &new_p64);
1276                 if (!err) {
1277                         aux_buf = new_p64 + sizeof(struct v4l2_buffer);
1278                         err = get_v4l2_buffer32(new_p64, p32,
1279                                                 aux_buf, aux_space);
1280                 }
1281                 compatible_arg = 0;
1282                 break;
1283
1284         case VIDIOC_S_FBUF32:
1285                 err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
1286                                       &new_p64);
1287                 if (!err)
1288                         err = get_v4l2_framebuffer32(new_p64, p32);
1289                 compatible_arg = 0;
1290                 break;
1291
1292         case VIDIOC_G_FBUF32:
1293                 err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
1294                                       &new_p64);
1295                 compatible_arg = 0;
1296                 break;
1297
1298         case VIDIOC_ENUMSTD32:
1299                 err = alloc_userspace(sizeof(struct v4l2_standard), 0,
1300                                       &new_p64);
1301                 if (!err)
1302                         err = get_v4l2_standard32(new_p64, p32);
1303                 compatible_arg = 0;
1304                 break;
1305
1306         case VIDIOC_ENUMINPUT32:
1307                 err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64);
1308                 if (!err)
1309                         err = get_v4l2_input32(new_p64, p32);
1310                 compatible_arg = 0;
1311                 break;
1312
1313         case VIDIOC_G_EXT_CTRLS32:
1314         case VIDIOC_S_EXT_CTRLS32:
1315         case VIDIOC_TRY_EXT_CTRLS32:
1316                 err = bufsize_v4l2_ext_controls(p32, &aux_space);
1317                 if (!err)
1318                         err = alloc_userspace(sizeof(struct v4l2_ext_controls),
1319                                               aux_space, &new_p64);
1320                 if (!err) {
1321                         aux_buf = new_p64 + sizeof(struct v4l2_ext_controls);
1322                         err = get_v4l2_ext_controls32(file, new_p64, p32,
1323                                                       aux_buf, aux_space);
1324                 }
1325                 compatible_arg = 0;
1326                 break;
1327         case VIDIOC_DQEVENT32:
1328                 err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64);
1329                 compatible_arg = 0;
1330                 break;
1331         }
1332         if (err)
1333                 return err;
1334
1335         /*
1336          * 3. Calls the native 64-bits ioctl handler.
1337          *
1338          * For the functions where a conversion was not needed,
1339          * compatible_arg is true, and it will call it with the arguments
1340          * provided by userspace and stored at @p32 var.
1341          *
1342          * Otherwise, it will pass the newly allocated @new_p64 argument.
1343          */
1344         if (compatible_arg)
1345                 err = native_ioctl(file, ncmd, (unsigned long)p32);
1346         else
1347                 err = native_ioctl(file, ncmd, (unsigned long)new_p64);
1348
1349         if (err == -ENOTTY)
1350                 return err;
1351
1352         /*
1353          * 4. Special case: even after an error we need to put the
1354          * results back for some ioctls.
1355          *
1356          * In the case of EXT_CTRLS, the error_idx will contain information
1357          * on which control failed.
1358          *
1359          * In the case of S_EDID, the driver can return E2BIG and set
1360          * the blocks to maximum allowed value.
1361          */
1362         switch (cmd) {
1363         case VIDIOC_G_EXT_CTRLS32:
1364         case VIDIOC_S_EXT_CTRLS32:
1365         case VIDIOC_TRY_EXT_CTRLS32:
1366                 if (put_v4l2_ext_controls32(file, new_p64, p32))
1367                         err = -EFAULT;
1368                 break;
1369         case VIDIOC_S_EDID32:
1370                 if (put_v4l2_edid32(new_p64, p32))
1371                         err = -EFAULT;
1372                 break;
1373         }
1374         if (err)
1375                 return err;
1376
1377         /*
1378          * 5. Copy the data returned at the 64 bits userspace pointer to
1379          * the original 32 bits structure.
1380          */
1381         switch (cmd) {
1382         case VIDIOC_S_INPUT32:
1383         case VIDIOC_S_OUTPUT32:
1384         case VIDIOC_G_INPUT32:
1385         case VIDIOC_G_OUTPUT32:
1386                 if (assign_in_user((compat_uint_t __user *)p32,
1387                                    ((unsigned int __user *)new_p64)))
1388                         err = -EFAULT;
1389                 break;
1390
1391         case VIDIOC_G_FBUF32:
1392                 err = put_v4l2_framebuffer32(new_p64, p32);
1393                 break;
1394
1395         case VIDIOC_DQEVENT32:
1396                 err = put_v4l2_event32(new_p64, p32);
1397                 break;
1398
1399         case VIDIOC_G_EDID32:
1400                 err = put_v4l2_edid32(new_p64, p32);
1401                 break;
1402
1403         case VIDIOC_G_FMT32:
1404         case VIDIOC_S_FMT32:
1405         case VIDIOC_TRY_FMT32:
1406                 err = put_v4l2_format32(new_p64, p32);
1407                 break;
1408
1409         case VIDIOC_CREATE_BUFS32:
1410                 err = put_v4l2_create32(new_p64, p32);
1411                 break;
1412
1413         case VIDIOC_PREPARE_BUF32:
1414         case VIDIOC_QUERYBUF32:
1415         case VIDIOC_QBUF32:
1416         case VIDIOC_DQBUF32:
1417                 err = put_v4l2_buffer32(new_p64, p32);
1418                 break;
1419
1420         case VIDIOC_ENUMSTD32:
1421                 err = put_v4l2_standard32(new_p64, p32);
1422                 break;
1423
1424         case VIDIOC_ENUMINPUT32:
1425                 err = put_v4l2_input32(new_p64, p32);
1426                 break;
1427         }
1428         return err;
1429 }
1430
1431 /**
1432  * v4l2_compat_ioctl32() - Handles a compat32 ioctl call
1433  *
1434  * @file: pointer to &struct file with the file handler
1435  * @cmd: ioctl to be called
1436  * @arg: arguments passed from/to the ioctl handler
1437  *
1438  * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c
1439  * in order to deal with 32-bit calls on a 64-bits Kernel.
1440  *
1441  * This function calls do_video_ioctl() for non-private V4L2 ioctls.
1442  * If the function is a private one it calls vdev->fops->compat_ioctl32
1443  * instead.
1444  */
1445 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1446 {
1447         struct video_device *vdev = video_devdata(file);
1448         long ret = -ENOIOCTLCMD;
1449
1450         if (!file->f_op->unlocked_ioctl)
1451                 return ret;
1452
1453         if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
1454                 ret = do_video_ioctl(file, cmd, arg);
1455         else if (vdev->fops->compat_ioctl32)
1456                 ret = vdev->fops->compat_ioctl32(file, cmd, arg);
1457
1458         if (ret == -ENOIOCTLCMD)
1459                 pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1460                          _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
1461         return ret;
1462 }
1463 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);