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 * Per-ioctl data copy handlers. 28 * 29 * Those come in pairs, with a get_v4l2_foo() and a put_v4l2_foo() routine, 30 * where "v4l2_foo" is the name of the V4L2 struct. 31 * 32 * They basically get two __user pointers, one with a 32-bits struct that 33 * came from the userspace call and a 64-bits struct, also allocated as 34 * userspace, but filled internally by do_video_ioctl(). 35 * 36 * For ioctls that have pointers inside it, the functions will also 37 * receive an ancillary buffer with extra space, used to pass extra 38 * data to the routine. 39 */ 40 41 struct v4l2_window32 { 42 struct v4l2_rect w; 43 __u32 field; /* enum v4l2_field */ 44 __u32 chromakey; 45 compat_caddr_t clips; /* always NULL */ 46 __u32 clipcount; /* always 0 */ 47 compat_caddr_t bitmap; /* always NULL */ 48 __u8 global_alpha; 49 }; 50 51 static int get_v4l2_window32(struct v4l2_window *p64, 52 struct v4l2_window32 __user *p32) 53 { 54 struct v4l2_window32 w32; 55 56 if (copy_from_user(&w32, p32, sizeof(w32))) 57 return -EFAULT; 58 59 *p64 = (struct v4l2_window) { 60 .w = w32.w, 61 .field = w32.field, 62 .chromakey = w32.chromakey, 63 .clips = NULL, 64 .clipcount = 0, 65 .bitmap = NULL, 66 .global_alpha = w32.global_alpha, 67 }; 68 69 return 0; 70 } 71 72 static int put_v4l2_window32(struct v4l2_window *p64, 73 struct v4l2_window32 __user *p32) 74 { 75 struct v4l2_window32 w32; 76 77 memset(&w32, 0, sizeof(w32)); 78 w32 = (struct v4l2_window32) { 79 .w = p64->w, 80 .field = p64->field, 81 .chromakey = p64->chromakey, 82 .clips = 0, 83 .clipcount = 0, 84 .bitmap = 0, 85 .global_alpha = p64->global_alpha, 86 }; 87 88 if (copy_to_user(p32, &w32, sizeof(w32))) 89 return -EFAULT; 90 91 return 0; 92 } 93 94 struct v4l2_format32 { 95 __u32 type; /* enum v4l2_buf_type */ 96 union { 97 struct v4l2_pix_format pix; 98 struct v4l2_pix_format_mplane pix_mp; 99 struct v4l2_window32 win; 100 struct v4l2_vbi_format vbi; 101 struct v4l2_sliced_vbi_format sliced; 102 struct v4l2_sdr_format sdr; 103 struct v4l2_meta_format meta; 104 __u8 raw_data[200]; /* user-defined */ 105 } fmt; 106 }; 107 108 /** 109 * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument 110 * @index: on return, index of the first created buffer 111 * @count: entry: number of requested buffers, 112 * return: number of created buffers 113 * @memory: buffer memory type 114 * @format: frame format, for which buffers are requested 115 * @capabilities: capabilities of this buffer type. 116 * @flags: additional buffer management attributes (ignored unless the 117 * queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability and 118 * configured for MMAP streaming I/O). 119 * @max_num_buffers: if V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS capability flag is set 120 * this field indicate the maximum possible number of buffers 121 * for this queue. 122 * @reserved: future extensions 123 */ 124 struct v4l2_create_buffers32 { 125 __u32 index; 126 __u32 count; 127 __u32 memory; /* enum v4l2_memory */ 128 struct v4l2_format32 format; 129 __u32 capabilities; 130 __u32 flags; 131 __u32 max_num_buffers; 132 __u32 reserved[5]; 133 }; 134 135 static int get_v4l2_format32(struct v4l2_format *p64, 136 struct v4l2_format32 __user *p32) 137 { 138 if (get_user(p64->type, &p32->type)) 139 return -EFAULT; 140 141 switch (p64->type) { 142 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 143 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 144 return copy_from_user(&p64->fmt.pix, &p32->fmt.pix, 145 sizeof(p64->fmt.pix)) ? -EFAULT : 0; 146 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 147 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 148 return copy_from_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp, 149 sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0; 150 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 151 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 152 return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win); 153 case V4L2_BUF_TYPE_VBI_CAPTURE: 154 case V4L2_BUF_TYPE_VBI_OUTPUT: 155 return copy_from_user(&p64->fmt.vbi, &p32->fmt.vbi, 156 sizeof(p64->fmt.vbi)) ? -EFAULT : 0; 157 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 158 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 159 return copy_from_user(&p64->fmt.sliced, &p32->fmt.sliced, 160 sizeof(p64->fmt.sliced)) ? -EFAULT : 0; 161 case V4L2_BUF_TYPE_SDR_CAPTURE: 162 case V4L2_BUF_TYPE_SDR_OUTPUT: 163 return copy_from_user(&p64->fmt.sdr, &p32->fmt.sdr, 164 sizeof(p64->fmt.sdr)) ? -EFAULT : 0; 165 case V4L2_BUF_TYPE_META_CAPTURE: 166 case V4L2_BUF_TYPE_META_OUTPUT: 167 return copy_from_user(&p64->fmt.meta, &p32->fmt.meta, 168 sizeof(p64->fmt.meta)) ? -EFAULT : 0; 169 default: 170 return -EINVAL; 171 } 172 } 173 174 static int get_v4l2_create32(struct v4l2_create_buffers *p64, 175 struct v4l2_create_buffers32 __user *p32) 176 { 177 if (copy_from_user(p64, p32, 178 offsetof(struct v4l2_create_buffers32, format))) 179 return -EFAULT; 180 if (copy_from_user(&p64->flags, &p32->flags, sizeof(p32->flags))) 181 return -EFAULT; 182 if (copy_from_user(&p64->max_num_buffers, &p32->max_num_buffers, 183 sizeof(p32->max_num_buffers))) 184 return -EFAULT; 185 return get_v4l2_format32(&p64->format, &p32->format); 186 } 187 188 static int put_v4l2_format32(struct v4l2_format *p64, 189 struct v4l2_format32 __user *p32) 190 { 191 switch (p64->type) { 192 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 193 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 194 return copy_to_user(&p32->fmt.pix, &p64->fmt.pix, 195 sizeof(p64->fmt.pix)) ? -EFAULT : 0; 196 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 197 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 198 return copy_to_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp, 199 sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0; 200 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 201 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 202 return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win); 203 case V4L2_BUF_TYPE_VBI_CAPTURE: 204 case V4L2_BUF_TYPE_VBI_OUTPUT: 205 return copy_to_user(&p32->fmt.vbi, &p64->fmt.vbi, 206 sizeof(p64->fmt.vbi)) ? -EFAULT : 0; 207 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 208 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 209 return copy_to_user(&p32->fmt.sliced, &p64->fmt.sliced, 210 sizeof(p64->fmt.sliced)) ? -EFAULT : 0; 211 case V4L2_BUF_TYPE_SDR_CAPTURE: 212 case V4L2_BUF_TYPE_SDR_OUTPUT: 213 return copy_to_user(&p32->fmt.sdr, &p64->fmt.sdr, 214 sizeof(p64->fmt.sdr)) ? -EFAULT : 0; 215 case V4L2_BUF_TYPE_META_CAPTURE: 216 case V4L2_BUF_TYPE_META_OUTPUT: 217 return copy_to_user(&p32->fmt.meta, &p64->fmt.meta, 218 sizeof(p64->fmt.meta)) ? -EFAULT : 0; 219 default: 220 return -EINVAL; 221 } 222 } 223 224 static int put_v4l2_create32(struct v4l2_create_buffers *p64, 225 struct v4l2_create_buffers32 __user *p32) 226 { 227 if (copy_to_user(p32, p64, 228 offsetof(struct v4l2_create_buffers32, format)) || 229 put_user(p64->capabilities, &p32->capabilities) || 230 put_user(p64->flags, &p32->flags) || 231 put_user(p64->max_num_buffers, &p32->max_num_buffers) || 232 copy_to_user(p32->reserved, p64->reserved, sizeof(p64->reserved))) 233 return -EFAULT; 234 return put_v4l2_format32(&p64->format, &p32->format); 235 } 236 237 struct v4l2_standard32 { 238 __u32 index; 239 compat_u64 id; 240 __u8 name[24]; 241 struct v4l2_fract frameperiod; /* Frames, not fields */ 242 __u32 framelines; 243 __u32 reserved[4]; 244 }; 245 246 static int get_v4l2_standard32(struct v4l2_standard *p64, 247 struct v4l2_standard32 __user *p32) 248 { 249 /* other fields are not set by the user, nor used by the driver */ 250 return get_user(p64->index, &p32->index); 251 } 252 253 static int put_v4l2_standard32(struct v4l2_standard *p64, 254 struct v4l2_standard32 __user *p32) 255 { 256 if (put_user(p64->index, &p32->index) || 257 put_user(p64->id, &p32->id) || 258 copy_to_user(p32->name, p64->name, sizeof(p32->name)) || 259 copy_to_user(&p32->frameperiod, &p64->frameperiod, 260 sizeof(p32->frameperiod)) || 261 put_user(p64->framelines, &p32->framelines) || 262 copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) 263 return -EFAULT; 264 return 0; 265 } 266 267 struct v4l2_plane32 { 268 __u32 bytesused; 269 __u32 length; 270 union { 271 __u32 mem_offset; 272 compat_long_t userptr; 273 __s32 fd; 274 } m; 275 __u32 data_offset; 276 __u32 reserved[11]; 277 }; 278 279 /* 280 * This is correct for all architectures including i386, but not x32, 281 * which has different alignment requirements for timestamp 282 */ 283 struct v4l2_buffer32 { 284 __u32 index; 285 __u32 type; /* enum v4l2_buf_type */ 286 __u32 bytesused; 287 __u32 flags; 288 __u32 field; /* enum v4l2_field */ 289 struct { 290 compat_s64 tv_sec; 291 compat_s64 tv_usec; 292 } timestamp; 293 struct v4l2_timecode timecode; 294 __u32 sequence; 295 296 /* memory location */ 297 __u32 memory; /* enum v4l2_memory */ 298 union { 299 __u32 offset; 300 compat_long_t userptr; 301 compat_caddr_t planes; 302 __s32 fd; 303 } m; 304 __u32 length; 305 __u32 reserved2; 306 __s32 request_fd; 307 }; 308 309 #ifdef CONFIG_COMPAT_32BIT_TIME 310 struct v4l2_buffer32_time32 { 311 __u32 index; 312 __u32 type; /* enum v4l2_buf_type */ 313 __u32 bytesused; 314 __u32 flags; 315 __u32 field; /* enum v4l2_field */ 316 struct old_timeval32 timestamp; 317 struct v4l2_timecode timecode; 318 __u32 sequence; 319 320 /* memory location */ 321 __u32 memory; /* enum v4l2_memory */ 322 union { 323 __u32 offset; 324 compat_long_t userptr; 325 compat_caddr_t planes; 326 __s32 fd; 327 } m; 328 __u32 length; 329 __u32 reserved2; 330 __s32 request_fd; 331 }; 332 #endif 333 334 static int get_v4l2_plane32(struct v4l2_plane *p64, 335 struct v4l2_plane32 __user *p32, 336 enum v4l2_memory memory) 337 { 338 struct v4l2_plane32 plane32; 339 typeof(p64->m) m = {}; 340 341 if (copy_from_user(&plane32, p32, sizeof(plane32))) 342 return -EFAULT; 343 344 switch (memory) { 345 case V4L2_MEMORY_MMAP: 346 case V4L2_MEMORY_OVERLAY: 347 m.mem_offset = plane32.m.mem_offset; 348 break; 349 case V4L2_MEMORY_USERPTR: 350 m.userptr = (unsigned long)compat_ptr(plane32.m.userptr); 351 break; 352 case V4L2_MEMORY_DMABUF: 353 m.fd = plane32.m.fd; 354 break; 355 } 356 357 memset(p64, 0, sizeof(*p64)); 358 *p64 = (struct v4l2_plane) { 359 .bytesused = plane32.bytesused, 360 .length = plane32.length, 361 .m = m, 362 .data_offset = plane32.data_offset, 363 }; 364 365 return 0; 366 } 367 368 static int put_v4l2_plane32(struct v4l2_plane *p64, 369 struct v4l2_plane32 __user *p32, 370 enum v4l2_memory memory) 371 { 372 struct v4l2_plane32 plane32; 373 374 memset(&plane32, 0, sizeof(plane32)); 375 plane32 = (struct v4l2_plane32) { 376 .bytesused = p64->bytesused, 377 .length = p64->length, 378 .data_offset = p64->data_offset, 379 }; 380 381 switch (memory) { 382 case V4L2_MEMORY_MMAP: 383 case V4L2_MEMORY_OVERLAY: 384 plane32.m.mem_offset = p64->m.mem_offset; 385 break; 386 case V4L2_MEMORY_USERPTR: 387 plane32.m.userptr = (uintptr_t)(p64->m.userptr); 388 break; 389 case V4L2_MEMORY_DMABUF: 390 plane32.m.fd = p64->m.fd; 391 break; 392 } 393 394 if (copy_to_user(p32, &plane32, sizeof(plane32))) 395 return -EFAULT; 396 397 return 0; 398 } 399 400 static int get_v4l2_buffer32(struct v4l2_buffer *vb, 401 struct v4l2_buffer32 __user *arg) 402 { 403 struct v4l2_buffer32 vb32; 404 405 if (copy_from_user(&vb32, arg, sizeof(vb32))) 406 return -EFAULT; 407 408 memset(vb, 0, sizeof(*vb)); 409 *vb = (struct v4l2_buffer) { 410 .index = vb32.index, 411 .type = vb32.type, 412 .bytesused = vb32.bytesused, 413 .flags = vb32.flags, 414 .field = vb32.field, 415 .timestamp.tv_sec = vb32.timestamp.tv_sec, 416 .timestamp.tv_usec = vb32.timestamp.tv_usec, 417 .timecode = vb32.timecode, 418 .sequence = vb32.sequence, 419 .memory = vb32.memory, 420 .m.offset = vb32.m.offset, 421 .length = vb32.length, 422 .request_fd = vb32.request_fd, 423 }; 424 425 switch (vb->memory) { 426 case V4L2_MEMORY_MMAP: 427 case V4L2_MEMORY_OVERLAY: 428 vb->m.offset = vb32.m.offset; 429 break; 430 case V4L2_MEMORY_USERPTR: 431 vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr); 432 break; 433 case V4L2_MEMORY_DMABUF: 434 vb->m.fd = vb32.m.fd; 435 break; 436 } 437 438 if (V4L2_TYPE_IS_MULTIPLANAR(vb->type)) 439 vb->m.planes = (void __force *) 440 compat_ptr(vb32.m.planes); 441 442 return 0; 443 } 444 445 #ifdef CONFIG_COMPAT_32BIT_TIME 446 static int get_v4l2_buffer32_time32(struct v4l2_buffer *vb, 447 struct v4l2_buffer32_time32 __user *arg) 448 { 449 struct v4l2_buffer32_time32 vb32; 450 451 if (copy_from_user(&vb32, arg, sizeof(vb32))) 452 return -EFAULT; 453 454 *vb = (struct v4l2_buffer) { 455 .index = vb32.index, 456 .type = vb32.type, 457 .bytesused = vb32.bytesused, 458 .flags = vb32.flags, 459 .field = vb32.field, 460 .timestamp.tv_sec = vb32.timestamp.tv_sec, 461 .timestamp.tv_usec = vb32.timestamp.tv_usec, 462 .timecode = vb32.timecode, 463 .sequence = vb32.sequence, 464 .memory = vb32.memory, 465 .m.offset = vb32.m.offset, 466 .length = vb32.length, 467 .request_fd = vb32.request_fd, 468 }; 469 switch (vb->memory) { 470 case V4L2_MEMORY_MMAP: 471 case V4L2_MEMORY_OVERLAY: 472 vb->m.offset = vb32.m.offset; 473 break; 474 case V4L2_MEMORY_USERPTR: 475 vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr); 476 break; 477 case V4L2_MEMORY_DMABUF: 478 vb->m.fd = vb32.m.fd; 479 break; 480 } 481 482 if (V4L2_TYPE_IS_MULTIPLANAR(vb->type)) 483 vb->m.planes = (void __force *) 484 compat_ptr(vb32.m.planes); 485 486 return 0; 487 } 488 #endif 489 490 static int put_v4l2_buffer32(struct v4l2_buffer *vb, 491 struct v4l2_buffer32 __user *arg) 492 { 493 struct v4l2_buffer32 vb32; 494 495 memset(&vb32, 0, sizeof(vb32)); 496 vb32 = (struct v4l2_buffer32) { 497 .index = vb->index, 498 .type = vb->type, 499 .bytesused = vb->bytesused, 500 .flags = vb->flags, 501 .field = vb->field, 502 .timestamp.tv_sec = vb->timestamp.tv_sec, 503 .timestamp.tv_usec = vb->timestamp.tv_usec, 504 .timecode = vb->timecode, 505 .sequence = vb->sequence, 506 .memory = vb->memory, 507 .m.offset = vb->m.offset, 508 .length = vb->length, 509 .request_fd = vb->request_fd, 510 }; 511 512 switch (vb->memory) { 513 case V4L2_MEMORY_MMAP: 514 case V4L2_MEMORY_OVERLAY: 515 vb32.m.offset = vb->m.offset; 516 break; 517 case V4L2_MEMORY_USERPTR: 518 vb32.m.userptr = (uintptr_t)(vb->m.userptr); 519 break; 520 case V4L2_MEMORY_DMABUF: 521 vb32.m.fd = vb->m.fd; 522 break; 523 } 524 525 if (V4L2_TYPE_IS_MULTIPLANAR(vb->type)) 526 vb32.m.planes = (uintptr_t)vb->m.planes; 527 528 if (copy_to_user(arg, &vb32, sizeof(vb32))) 529 return -EFAULT; 530 531 return 0; 532 } 533 534 #ifdef CONFIG_COMPAT_32BIT_TIME 535 static int put_v4l2_buffer32_time32(struct v4l2_buffer *vb, 536 struct v4l2_buffer32_time32 __user *arg) 537 { 538 struct v4l2_buffer32_time32 vb32; 539 540 memset(&vb32, 0, sizeof(vb32)); 541 vb32 = (struct v4l2_buffer32_time32) { 542 .index = vb->index, 543 .type = vb->type, 544 .bytesused = vb->bytesused, 545 .flags = vb->flags, 546 .field = vb->field, 547 .timestamp.tv_sec = vb->timestamp.tv_sec, 548 .timestamp.tv_usec = vb->timestamp.tv_usec, 549 .timecode = vb->timecode, 550 .sequence = vb->sequence, 551 .memory = vb->memory, 552 .m.offset = vb->m.offset, 553 .length = vb->length, 554 .request_fd = vb->request_fd, 555 }; 556 switch (vb->memory) { 557 case V4L2_MEMORY_MMAP: 558 case V4L2_MEMORY_OVERLAY: 559 vb32.m.offset = vb->m.offset; 560 break; 561 case V4L2_MEMORY_USERPTR: 562 vb32.m.userptr = (uintptr_t)(vb->m.userptr); 563 break; 564 case V4L2_MEMORY_DMABUF: 565 vb32.m.fd = vb->m.fd; 566 break; 567 } 568 569 if (V4L2_TYPE_IS_MULTIPLANAR(vb->type)) 570 vb32.m.planes = (uintptr_t)vb->m.planes; 571 572 if (copy_to_user(arg, &vb32, sizeof(vb32))) 573 return -EFAULT; 574 575 return 0; 576 } 577 #endif 578 579 struct v4l2_framebuffer32 { 580 __u32 capability; 581 __u32 flags; 582 compat_caddr_t base; 583 struct { 584 __u32 width; 585 __u32 height; 586 __u32 pixelformat; 587 __u32 field; 588 __u32 bytesperline; 589 __u32 sizeimage; 590 __u32 colorspace; 591 __u32 priv; 592 } fmt; 593 }; 594 595 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *p64, 596 struct v4l2_framebuffer32 __user *p32) 597 { 598 if (get_user(p64->capability, &p32->capability) || 599 get_user(p64->flags, &p32->flags) || 600 copy_from_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt))) 601 return -EFAULT; 602 p64->base = NULL; 603 604 return 0; 605 } 606 607 static int put_v4l2_framebuffer32(struct v4l2_framebuffer *p64, 608 struct v4l2_framebuffer32 __user *p32) 609 { 610 if (put_user((uintptr_t)p64->base, &p32->base) || 611 put_user(p64->capability, &p32->capability) || 612 put_user(p64->flags, &p32->flags) || 613 copy_to_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt))) 614 return -EFAULT; 615 616 return 0; 617 } 618 619 struct v4l2_input32 { 620 __u32 index; /* Which input */ 621 __u8 name[32]; /* Label */ 622 __u32 type; /* Type of input */ 623 __u32 audioset; /* Associated audios (bitfield) */ 624 __u32 tuner; /* Associated tuner */ 625 compat_u64 std; 626 __u32 status; 627 __u32 capabilities; 628 __u32 reserved[3]; 629 }; 630 631 /* 632 * The 64-bit v4l2_input struct has extra padding at the end of the struct. 633 * Otherwise it is identical to the 32-bit version. 634 */ 635 static inline int get_v4l2_input32(struct v4l2_input *p64, 636 struct v4l2_input32 __user *p32) 637 { 638 if (copy_from_user(p64, p32, sizeof(*p32))) 639 return -EFAULT; 640 return 0; 641 } 642 643 static inline int put_v4l2_input32(struct v4l2_input *p64, 644 struct v4l2_input32 __user *p32) 645 { 646 if (copy_to_user(p32, p64, sizeof(*p32))) 647 return -EFAULT; 648 return 0; 649 } 650 651 struct v4l2_ext_controls32 { 652 __u32 which; 653 __u32 count; 654 __u32 error_idx; 655 __s32 request_fd; 656 __u32 reserved[1]; 657 compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */ 658 }; 659 660 struct v4l2_ext_control32 { 661 __u32 id; 662 __u32 size; 663 __u32 reserved2[1]; 664 union { 665 __s32 value; 666 __s64 value64; 667 compat_caddr_t string; /* actually char * */ 668 }; 669 } __attribute__ ((packed)); 670 671 /* Return true if this control is a pointer type. */ 672 static inline bool ctrl_is_pointer(struct file *file, u32 id) 673 { 674 struct video_device *vdev = video_devdata(file); 675 struct v4l2_fh *fh = NULL; 676 struct v4l2_ctrl_handler *hdl = NULL; 677 struct v4l2_query_ext_ctrl qec = { id }; 678 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; 679 680 if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) 681 fh = file->private_data; 682 683 if (fh && fh->ctrl_handler) 684 hdl = fh->ctrl_handler; 685 else if (vdev->ctrl_handler) 686 hdl = vdev->ctrl_handler; 687 688 if (hdl) { 689 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id); 690 691 return ctrl && ctrl->is_ptr; 692 } 693 694 if (!ops || !ops->vidioc_query_ext_ctrl) 695 return false; 696 697 return !ops->vidioc_query_ext_ctrl(file, fh, &qec) && 698 (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD); 699 } 700 701 static int get_v4l2_ext_controls32(struct v4l2_ext_controls *p64, 702 struct v4l2_ext_controls32 __user *p32) 703 { 704 struct v4l2_ext_controls32 ec32; 705 706 if (copy_from_user(&ec32, p32, sizeof(ec32))) 707 return -EFAULT; 708 709 *p64 = (struct v4l2_ext_controls) { 710 .which = ec32.which, 711 .count = ec32.count, 712 .error_idx = ec32.error_idx, 713 .request_fd = ec32.request_fd, 714 .reserved[0] = ec32.reserved[0], 715 .controls = (void __force *)compat_ptr(ec32.controls), 716 }; 717 718 return 0; 719 } 720 721 static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64, 722 struct v4l2_ext_controls32 __user *p32) 723 { 724 struct v4l2_ext_controls32 ec32; 725 726 memset(&ec32, 0, sizeof(ec32)); 727 ec32 = (struct v4l2_ext_controls32) { 728 .which = p64->which, 729 .count = p64->count, 730 .error_idx = p64->error_idx, 731 .request_fd = p64->request_fd, 732 .reserved[0] = p64->reserved[0], 733 .controls = (uintptr_t)p64->controls, 734 }; 735 736 if (copy_to_user(p32, &ec32, sizeof(ec32))) 737 return -EFAULT; 738 739 return 0; 740 } 741 742 #ifdef CONFIG_X86_64 743 /* 744 * x86 is the only compat architecture with different struct alignment 745 * between 32-bit and 64-bit tasks. 746 */ 747 struct v4l2_event32 { 748 __u32 type; 749 union { 750 compat_s64 value64; 751 __u8 data[64]; 752 } u; 753 __u32 pending; 754 __u32 sequence; 755 struct { 756 compat_s64 tv_sec; 757 compat_s64 tv_nsec; 758 } timestamp; 759 __u32 id; 760 __u32 reserved[8]; 761 }; 762 763 static int put_v4l2_event32(struct v4l2_event *p64, 764 struct v4l2_event32 __user *p32) 765 { 766 if (put_user(p64->type, &p32->type) || 767 copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) || 768 put_user(p64->pending, &p32->pending) || 769 put_user(p64->sequence, &p32->sequence) || 770 put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) || 771 put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) || 772 put_user(p64->id, &p32->id) || 773 copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) 774 return -EFAULT; 775 return 0; 776 } 777 778 #endif 779 780 #ifdef CONFIG_COMPAT_32BIT_TIME 781 struct v4l2_event32_time32 { 782 __u32 type; 783 union { 784 compat_s64 value64; 785 __u8 data[64]; 786 } u; 787 __u32 pending; 788 __u32 sequence; 789 struct old_timespec32 timestamp; 790 __u32 id; 791 __u32 reserved[8]; 792 }; 793 794 static int put_v4l2_event32_time32(struct v4l2_event *p64, 795 struct v4l2_event32_time32 __user *p32) 796 { 797 if (put_user(p64->type, &p32->type) || 798 copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) || 799 put_user(p64->pending, &p32->pending) || 800 put_user(p64->sequence, &p32->sequence) || 801 put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) || 802 put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) || 803 put_user(p64->id, &p32->id) || 804 copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) 805 return -EFAULT; 806 return 0; 807 } 808 #endif 809 810 struct v4l2_edid32 { 811 __u32 pad; 812 __u32 start_block; 813 __u32 blocks; 814 __u32 reserved[5]; 815 compat_caddr_t edid; 816 }; 817 818 static int get_v4l2_edid32(struct v4l2_edid *p64, 819 struct v4l2_edid32 __user *p32) 820 { 821 compat_uptr_t edid; 822 823 if (copy_from_user(p64, p32, offsetof(struct v4l2_edid32, edid)) || 824 get_user(edid, &p32->edid)) 825 return -EFAULT; 826 827 p64->edid = (void __force *)compat_ptr(edid); 828 return 0; 829 } 830 831 static int put_v4l2_edid32(struct v4l2_edid *p64, 832 struct v4l2_edid32 __user *p32) 833 { 834 if (copy_to_user(p32, p64, offsetof(struct v4l2_edid32, edid))) 835 return -EFAULT; 836 return 0; 837 } 838 839 /* 840 * List of ioctls that require 32-bits/64-bits conversion 841 * 842 * The V4L2 ioctls that aren't listed there don't have pointer arguments 843 * and the struct size is identical for both 32 and 64 bits versions, so 844 * they don't need translations. 845 */ 846 847 #define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32) 848 #define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32) 849 #define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32) 850 #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) 851 #define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) 852 #define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32) 853 #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32) 854 #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32) 855 #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) 856 #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32) 857 #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32) 858 #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) 859 #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) 860 #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) 861 #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 862 #define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32) 863 #define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32) 864 #define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32) 865 866 #ifdef CONFIG_COMPAT_32BIT_TIME 867 #define VIDIOC_QUERYBUF32_TIME32 _IOWR('V', 9, struct v4l2_buffer32_time32) 868 #define VIDIOC_QBUF32_TIME32 _IOWR('V', 15, struct v4l2_buffer32_time32) 869 #define VIDIOC_DQBUF32_TIME32 _IOWR('V', 17, struct v4l2_buffer32_time32) 870 #define VIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct v4l2_event32_time32) 871 #define VIDIOC_PREPARE_BUF32_TIME32 _IOWR('V', 93, struct v4l2_buffer32_time32) 872 #endif 873 874 unsigned int v4l2_compat_translate_cmd(unsigned int cmd) 875 { 876 switch (cmd) { 877 case VIDIOC_G_FMT32: 878 return VIDIOC_G_FMT; 879 case VIDIOC_S_FMT32: 880 return VIDIOC_S_FMT; 881 case VIDIOC_TRY_FMT32: 882 return VIDIOC_TRY_FMT; 883 case VIDIOC_G_FBUF32: 884 return VIDIOC_G_FBUF; 885 case VIDIOC_S_FBUF32: 886 return VIDIOC_S_FBUF; 887 #ifdef CONFIG_COMPAT_32BIT_TIME 888 case VIDIOC_QUERYBUF32_TIME32: 889 return VIDIOC_QUERYBUF; 890 case VIDIOC_QBUF32_TIME32: 891 return VIDIOC_QBUF; 892 case VIDIOC_DQBUF32_TIME32: 893 return VIDIOC_DQBUF; 894 case VIDIOC_PREPARE_BUF32_TIME32: 895 return VIDIOC_PREPARE_BUF; 896 #endif 897 case VIDIOC_QUERYBUF32: 898 return VIDIOC_QUERYBUF; 899 case VIDIOC_QBUF32: 900 return VIDIOC_QBUF; 901 case VIDIOC_DQBUF32: 902 return VIDIOC_DQBUF; 903 case VIDIOC_CREATE_BUFS32: 904 return VIDIOC_CREATE_BUFS; 905 case VIDIOC_G_EXT_CTRLS32: 906 return VIDIOC_G_EXT_CTRLS; 907 case VIDIOC_S_EXT_CTRLS32: 908 return VIDIOC_S_EXT_CTRLS; 909 case VIDIOC_TRY_EXT_CTRLS32: 910 return VIDIOC_TRY_EXT_CTRLS; 911 case VIDIOC_PREPARE_BUF32: 912 return VIDIOC_PREPARE_BUF; 913 case VIDIOC_ENUMSTD32: 914 return VIDIOC_ENUMSTD; 915 case VIDIOC_ENUMINPUT32: 916 return VIDIOC_ENUMINPUT; 917 case VIDIOC_G_EDID32: 918 return VIDIOC_G_EDID; 919 case VIDIOC_S_EDID32: 920 return VIDIOC_S_EDID; 921 #ifdef CONFIG_X86_64 922 case VIDIOC_DQEVENT32: 923 return VIDIOC_DQEVENT; 924 #endif 925 #ifdef CONFIG_COMPAT_32BIT_TIME 926 case VIDIOC_DQEVENT32_TIME32: 927 return VIDIOC_DQEVENT; 928 #endif 929 } 930 return cmd; 931 } 932 933 int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd) 934 { 935 switch (cmd) { 936 case VIDIOC_G_FMT32: 937 case VIDIOC_S_FMT32: 938 case VIDIOC_TRY_FMT32: 939 return get_v4l2_format32(parg, arg); 940 941 case VIDIOC_S_FBUF32: 942 return get_v4l2_framebuffer32(parg, arg); 943 #ifdef CONFIG_COMPAT_32BIT_TIME 944 case VIDIOC_QUERYBUF32_TIME32: 945 case VIDIOC_QBUF32_TIME32: 946 case VIDIOC_DQBUF32_TIME32: 947 case VIDIOC_PREPARE_BUF32_TIME32: 948 return get_v4l2_buffer32_time32(parg, arg); 949 #endif 950 case VIDIOC_QUERYBUF32: 951 case VIDIOC_QBUF32: 952 case VIDIOC_DQBUF32: 953 case VIDIOC_PREPARE_BUF32: 954 return get_v4l2_buffer32(parg, arg); 955 956 case VIDIOC_G_EXT_CTRLS32: 957 case VIDIOC_S_EXT_CTRLS32: 958 case VIDIOC_TRY_EXT_CTRLS32: 959 return get_v4l2_ext_controls32(parg, arg); 960 961 case VIDIOC_CREATE_BUFS32: 962 return get_v4l2_create32(parg, arg); 963 964 case VIDIOC_ENUMSTD32: 965 return get_v4l2_standard32(parg, arg); 966 967 case VIDIOC_ENUMINPUT32: 968 return get_v4l2_input32(parg, arg); 969 970 case VIDIOC_G_EDID32: 971 case VIDIOC_S_EDID32: 972 return get_v4l2_edid32(parg, arg); 973 } 974 return 0; 975 } 976 977 int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd) 978 { 979 switch (cmd) { 980 case VIDIOC_G_FMT32: 981 case VIDIOC_S_FMT32: 982 case VIDIOC_TRY_FMT32: 983 return put_v4l2_format32(parg, arg); 984 985 case VIDIOC_G_FBUF32: 986 return put_v4l2_framebuffer32(parg, arg); 987 #ifdef CONFIG_COMPAT_32BIT_TIME 988 case VIDIOC_QUERYBUF32_TIME32: 989 case VIDIOC_QBUF32_TIME32: 990 case VIDIOC_DQBUF32_TIME32: 991 case VIDIOC_PREPARE_BUF32_TIME32: 992 return put_v4l2_buffer32_time32(parg, arg); 993 #endif 994 case VIDIOC_QUERYBUF32: 995 case VIDIOC_QBUF32: 996 case VIDIOC_DQBUF32: 997 case VIDIOC_PREPARE_BUF32: 998 return put_v4l2_buffer32(parg, arg); 999 1000 case VIDIOC_G_EXT_CTRLS32: 1001 case VIDIOC_S_EXT_CTRLS32: 1002 case VIDIOC_TRY_EXT_CTRLS32: 1003 return put_v4l2_ext_controls32(parg, arg); 1004 1005 case VIDIOC_CREATE_BUFS32: 1006 return put_v4l2_create32(parg, arg); 1007 1008 case VIDIOC_ENUMSTD32: 1009 return put_v4l2_standard32(parg, arg); 1010 1011 case VIDIOC_ENUMINPUT32: 1012 return put_v4l2_input32(parg, arg); 1013 1014 case VIDIOC_G_EDID32: 1015 case VIDIOC_S_EDID32: 1016 return put_v4l2_edid32(parg, arg); 1017 #ifdef CONFIG_X86_64 1018 case VIDIOC_DQEVENT32: 1019 return put_v4l2_event32(parg, arg); 1020 #endif 1021 #ifdef CONFIG_COMPAT_32BIT_TIME 1022 case VIDIOC_DQEVENT32_TIME32: 1023 return put_v4l2_event32_time32(parg, arg); 1024 #endif 1025 } 1026 return 0; 1027 } 1028 1029 int v4l2_compat_get_array_args(struct file *file, void *mbuf, 1030 void __user *user_ptr, size_t array_size, 1031 unsigned int cmd, void *arg) 1032 { 1033 int err = 0; 1034 1035 memset(mbuf, 0, array_size); 1036 1037 switch (cmd) { 1038 #ifdef CONFIG_COMPAT_32BIT_TIME 1039 case VIDIOC_QUERYBUF32_TIME32: 1040 case VIDIOC_QBUF32_TIME32: 1041 case VIDIOC_DQBUF32_TIME32: 1042 case VIDIOC_PREPARE_BUF32_TIME32: 1043 #endif 1044 case VIDIOC_QUERYBUF32: 1045 case VIDIOC_QBUF32: 1046 case VIDIOC_DQBUF32: 1047 case VIDIOC_PREPARE_BUF32: { 1048 struct v4l2_buffer *b64 = arg; 1049 struct v4l2_plane *p64 = mbuf; 1050 struct v4l2_plane32 __user *p32 = user_ptr; 1051 1052 if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) { 1053 u32 num_planes = b64->length; 1054 1055 if (num_planes == 0) 1056 return 0; 1057 1058 while (num_planes--) { 1059 err = get_v4l2_plane32(p64, p32, b64->memory); 1060 if (err) 1061 return err; 1062 ++p64; 1063 ++p32; 1064 } 1065 } 1066 break; 1067 } 1068 case VIDIOC_G_EXT_CTRLS32: 1069 case VIDIOC_S_EXT_CTRLS32: 1070 case VIDIOC_TRY_EXT_CTRLS32: { 1071 struct v4l2_ext_controls *ecs64 = arg; 1072 struct v4l2_ext_control *ec64 = mbuf; 1073 struct v4l2_ext_control32 __user *ec32 = user_ptr; 1074 int n; 1075 1076 for (n = 0; n < ecs64->count; n++) { 1077 if (copy_from_user(ec64, ec32, sizeof(*ec32))) 1078 return -EFAULT; 1079 1080 if (ctrl_is_pointer(file, ec64->id)) { 1081 compat_uptr_t p; 1082 1083 if (get_user(p, &ec32->string)) 1084 return -EFAULT; 1085 ec64->string = compat_ptr(p); 1086 } 1087 ec32++; 1088 ec64++; 1089 } 1090 break; 1091 } 1092 default: 1093 if (copy_from_user(mbuf, user_ptr, array_size)) 1094 err = -EFAULT; 1095 break; 1096 } 1097 1098 return err; 1099 } 1100 1101 int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr, 1102 void *mbuf, size_t array_size, 1103 unsigned int cmd, void *arg) 1104 { 1105 int err = 0; 1106 1107 switch (cmd) { 1108 #ifdef CONFIG_COMPAT_32BIT_TIME 1109 case VIDIOC_QUERYBUF32_TIME32: 1110 case VIDIOC_QBUF32_TIME32: 1111 case VIDIOC_DQBUF32_TIME32: 1112 case VIDIOC_PREPARE_BUF32_TIME32: 1113 #endif 1114 case VIDIOC_QUERYBUF32: 1115 case VIDIOC_QBUF32: 1116 case VIDIOC_DQBUF32: 1117 case VIDIOC_PREPARE_BUF32: { 1118 struct v4l2_buffer *b64 = arg; 1119 struct v4l2_plane *p64 = mbuf; 1120 struct v4l2_plane32 __user *p32 = user_ptr; 1121 1122 if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) { 1123 u32 num_planes = b64->length; 1124 1125 if (num_planes == 0) 1126 return 0; 1127 1128 while (num_planes--) { 1129 err = put_v4l2_plane32(p64, p32, b64->memory); 1130 if (err) 1131 return err; 1132 ++p64; 1133 ++p32; 1134 } 1135 } 1136 break; 1137 } 1138 case VIDIOC_G_EXT_CTRLS32: 1139 case VIDIOC_S_EXT_CTRLS32: 1140 case VIDIOC_TRY_EXT_CTRLS32: { 1141 struct v4l2_ext_controls *ecs64 = arg; 1142 struct v4l2_ext_control *ec64 = mbuf; 1143 struct v4l2_ext_control32 __user *ec32 = user_ptr; 1144 int n; 1145 1146 for (n = 0; n < ecs64->count; n++) { 1147 unsigned int size = sizeof(*ec32); 1148 /* 1149 * Do not modify the pointer when copying a pointer 1150 * control. The contents of the pointer was changed, 1151 * not the pointer itself. 1152 * The structures are otherwise compatible. 1153 */ 1154 if (ctrl_is_pointer(file, ec64->id)) 1155 size -= sizeof(ec32->value64); 1156 1157 if (copy_to_user(ec32, ec64, size)) 1158 return -EFAULT; 1159 1160 ec32++; 1161 ec64++; 1162 } 1163 break; 1164 } 1165 default: 1166 if (copy_to_user(user_ptr, mbuf, array_size)) 1167 err = -EFAULT; 1168 break; 1169 } 1170 1171 return err; 1172 } 1173 1174 /** 1175 * v4l2_compat_ioctl32() - Handles a compat32 ioctl call 1176 * 1177 * @file: pointer to &struct file with the file handler 1178 * @cmd: ioctl to be called 1179 * @arg: arguments passed from/to the ioctl handler 1180 * 1181 * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c 1182 * in order to deal with 32-bit calls on a 64-bits Kernel. 1183 * 1184 * This function calls do_video_ioctl() for non-private V4L2 ioctls. 1185 * If the function is a private one it calls vdev->fops->compat_ioctl32 1186 * instead. 1187 */ 1188 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) 1189 { 1190 struct video_device *vdev = video_devdata(file); 1191 long ret = -ENOIOCTLCMD; 1192 1193 if (!file->f_op->unlocked_ioctl) 1194 return ret; 1195 1196 if (!video_is_registered(vdev)) 1197 return -ENODEV; 1198 1199 if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) 1200 ret = file->f_op->unlocked_ioctl(file, cmd, 1201 (unsigned long)compat_ptr(arg)); 1202 else if (vdev->fops->compat_ioctl32) 1203 ret = vdev->fops->compat_ioctl32(file, cmd, arg); 1204 1205 if (ret == -ENOIOCTLCMD) 1206 pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", 1207 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); 1208 return ret; 1209 } 1210 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); 1211