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