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@kernel.org> 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 = file_to_v4l2_fh(file); 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 (fh->ctrl_handler) 681 hdl = fh->ctrl_handler; 682 else if (vdev->ctrl_handler) 683 hdl = vdev->ctrl_handler; 684 685 if (hdl) { 686 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id); 687 688 return ctrl && ctrl->is_ptr; 689 } 690 691 if (!ops || !ops->vidioc_query_ext_ctrl) 692 return false; 693 694 return !ops->vidioc_query_ext_ctrl(file, NULL, &qec) && 695 (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD); 696 } 697 698 static int get_v4l2_ext_controls32(struct v4l2_ext_controls *p64, 699 struct v4l2_ext_controls32 __user *p32) 700 { 701 struct v4l2_ext_controls32 ec32; 702 703 if (copy_from_user(&ec32, p32, sizeof(ec32))) 704 return -EFAULT; 705 706 *p64 = (struct v4l2_ext_controls) { 707 .which = ec32.which, 708 .count = ec32.count, 709 .error_idx = ec32.error_idx, 710 .request_fd = ec32.request_fd, 711 .reserved[0] = ec32.reserved[0], 712 .controls = (void __force *)compat_ptr(ec32.controls), 713 }; 714 715 return 0; 716 } 717 718 static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64, 719 struct v4l2_ext_controls32 __user *p32) 720 { 721 struct v4l2_ext_controls32 ec32; 722 723 memset(&ec32, 0, sizeof(ec32)); 724 ec32 = (struct v4l2_ext_controls32) { 725 .which = p64->which, 726 .count = p64->count, 727 .error_idx = p64->error_idx, 728 .request_fd = p64->request_fd, 729 .reserved[0] = p64->reserved[0], 730 .controls = (uintptr_t)p64->controls, 731 }; 732 733 if (copy_to_user(p32, &ec32, sizeof(ec32))) 734 return -EFAULT; 735 736 return 0; 737 } 738 739 #ifdef CONFIG_X86_64 740 /* 741 * x86 is the only compat architecture with different struct alignment 742 * between 32-bit and 64-bit tasks. 743 */ 744 struct v4l2_event32 { 745 __u32 type; 746 union { 747 compat_s64 value64; 748 __u8 data[64]; 749 } u; 750 __u32 pending; 751 __u32 sequence; 752 struct { 753 compat_s64 tv_sec; 754 compat_s64 tv_nsec; 755 } timestamp; 756 __u32 id; 757 __u32 reserved[8]; 758 }; 759 760 static int put_v4l2_event32(struct v4l2_event *p64, 761 struct v4l2_event32 __user *p32) 762 { 763 if (put_user(p64->type, &p32->type) || 764 copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) || 765 put_user(p64->pending, &p32->pending) || 766 put_user(p64->sequence, &p32->sequence) || 767 put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) || 768 put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) || 769 put_user(p64->id, &p32->id) || 770 copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) 771 return -EFAULT; 772 return 0; 773 } 774 775 #endif 776 777 #ifdef CONFIG_COMPAT_32BIT_TIME 778 struct v4l2_event32_time32 { 779 __u32 type; 780 union { 781 compat_s64 value64; 782 __u8 data[64]; 783 } u; 784 __u32 pending; 785 __u32 sequence; 786 struct old_timespec32 timestamp; 787 __u32 id; 788 __u32 reserved[8]; 789 }; 790 791 static int put_v4l2_event32_time32(struct v4l2_event *p64, 792 struct v4l2_event32_time32 __user *p32) 793 { 794 if (put_user(p64->type, &p32->type) || 795 copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) || 796 put_user(p64->pending, &p32->pending) || 797 put_user(p64->sequence, &p32->sequence) || 798 put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) || 799 put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) || 800 put_user(p64->id, &p32->id) || 801 copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) 802 return -EFAULT; 803 return 0; 804 } 805 #endif 806 807 struct v4l2_edid32 { 808 __u32 pad; 809 __u32 start_block; 810 __u32 blocks; 811 __u32 reserved[5]; 812 compat_caddr_t edid; 813 }; 814 815 static int get_v4l2_edid32(struct v4l2_edid *p64, 816 struct v4l2_edid32 __user *p32) 817 { 818 compat_uptr_t edid; 819 820 if (copy_from_user(p64, p32, offsetof(struct v4l2_edid32, edid)) || 821 get_user(edid, &p32->edid)) 822 return -EFAULT; 823 824 p64->edid = (void __force *)compat_ptr(edid); 825 return 0; 826 } 827 828 static int put_v4l2_edid32(struct v4l2_edid *p64, 829 struct v4l2_edid32 __user *p32) 830 { 831 if (copy_to_user(p32, p64, offsetof(struct v4l2_edid32, edid))) 832 return -EFAULT; 833 return 0; 834 } 835 836 /* 837 * List of ioctls that require 32-bits/64-bits conversion 838 * 839 * The V4L2 ioctls that aren't listed there don't have pointer arguments 840 * and the struct size is identical for both 32 and 64 bits versions, so 841 * they don't need translations. 842 */ 843 844 #define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32) 845 #define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32) 846 #define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32) 847 #define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) 848 #define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) 849 #define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32) 850 #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32) 851 #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32) 852 #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) 853 #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32) 854 #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32) 855 #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) 856 #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) 857 #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) 858 #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 859 #define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32) 860 #define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32) 861 #define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32) 862 863 #ifdef CONFIG_COMPAT_32BIT_TIME 864 #define VIDIOC_QUERYBUF32_TIME32 _IOWR('V', 9, struct v4l2_buffer32_time32) 865 #define VIDIOC_QBUF32_TIME32 _IOWR('V', 15, struct v4l2_buffer32_time32) 866 #define VIDIOC_DQBUF32_TIME32 _IOWR('V', 17, struct v4l2_buffer32_time32) 867 #define VIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct v4l2_event32_time32) 868 #define VIDIOC_PREPARE_BUF32_TIME32 _IOWR('V', 93, struct v4l2_buffer32_time32) 869 #endif 870 871 unsigned int v4l2_compat_translate_cmd(unsigned int cmd) 872 { 873 switch (cmd) { 874 case VIDIOC_G_FMT32: 875 return VIDIOC_G_FMT; 876 case VIDIOC_S_FMT32: 877 return VIDIOC_S_FMT; 878 case VIDIOC_TRY_FMT32: 879 return VIDIOC_TRY_FMT; 880 case VIDIOC_G_FBUF32: 881 return VIDIOC_G_FBUF; 882 case VIDIOC_S_FBUF32: 883 return VIDIOC_S_FBUF; 884 #ifdef CONFIG_COMPAT_32BIT_TIME 885 case VIDIOC_QUERYBUF32_TIME32: 886 return VIDIOC_QUERYBUF; 887 case VIDIOC_QBUF32_TIME32: 888 return VIDIOC_QBUF; 889 case VIDIOC_DQBUF32_TIME32: 890 return VIDIOC_DQBUF; 891 case VIDIOC_PREPARE_BUF32_TIME32: 892 return VIDIOC_PREPARE_BUF; 893 #endif 894 case VIDIOC_QUERYBUF32: 895 return VIDIOC_QUERYBUF; 896 case VIDIOC_QBUF32: 897 return VIDIOC_QBUF; 898 case VIDIOC_DQBUF32: 899 return VIDIOC_DQBUF; 900 case VIDIOC_CREATE_BUFS32: 901 return VIDIOC_CREATE_BUFS; 902 case VIDIOC_G_EXT_CTRLS32: 903 return VIDIOC_G_EXT_CTRLS; 904 case VIDIOC_S_EXT_CTRLS32: 905 return VIDIOC_S_EXT_CTRLS; 906 case VIDIOC_TRY_EXT_CTRLS32: 907 return VIDIOC_TRY_EXT_CTRLS; 908 case VIDIOC_PREPARE_BUF32: 909 return VIDIOC_PREPARE_BUF; 910 case VIDIOC_ENUMSTD32: 911 return VIDIOC_ENUMSTD; 912 case VIDIOC_ENUMINPUT32: 913 return VIDIOC_ENUMINPUT; 914 case VIDIOC_G_EDID32: 915 return VIDIOC_G_EDID; 916 case VIDIOC_S_EDID32: 917 return VIDIOC_S_EDID; 918 #ifdef CONFIG_X86_64 919 case VIDIOC_DQEVENT32: 920 return VIDIOC_DQEVENT; 921 #endif 922 #ifdef CONFIG_COMPAT_32BIT_TIME 923 case VIDIOC_DQEVENT32_TIME32: 924 return VIDIOC_DQEVENT; 925 #endif 926 } 927 return cmd; 928 } 929 930 int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd) 931 { 932 switch (cmd) { 933 case VIDIOC_G_FMT32: 934 case VIDIOC_S_FMT32: 935 case VIDIOC_TRY_FMT32: 936 return get_v4l2_format32(parg, arg); 937 938 case VIDIOC_S_FBUF32: 939 return get_v4l2_framebuffer32(parg, arg); 940 #ifdef CONFIG_COMPAT_32BIT_TIME 941 case VIDIOC_QUERYBUF32_TIME32: 942 case VIDIOC_QBUF32_TIME32: 943 case VIDIOC_DQBUF32_TIME32: 944 case VIDIOC_PREPARE_BUF32_TIME32: 945 return get_v4l2_buffer32_time32(parg, arg); 946 #endif 947 case VIDIOC_QUERYBUF32: 948 case VIDIOC_QBUF32: 949 case VIDIOC_DQBUF32: 950 case VIDIOC_PREPARE_BUF32: 951 return get_v4l2_buffer32(parg, arg); 952 953 case VIDIOC_G_EXT_CTRLS32: 954 case VIDIOC_S_EXT_CTRLS32: 955 case VIDIOC_TRY_EXT_CTRLS32: 956 return get_v4l2_ext_controls32(parg, arg); 957 958 case VIDIOC_CREATE_BUFS32: 959 return get_v4l2_create32(parg, arg); 960 961 case VIDIOC_ENUMSTD32: 962 return get_v4l2_standard32(parg, arg); 963 964 case VIDIOC_ENUMINPUT32: 965 return get_v4l2_input32(parg, arg); 966 967 case VIDIOC_G_EDID32: 968 case VIDIOC_S_EDID32: 969 return get_v4l2_edid32(parg, arg); 970 } 971 return 0; 972 } 973 974 int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd) 975 { 976 switch (cmd) { 977 case VIDIOC_G_FMT32: 978 case VIDIOC_S_FMT32: 979 case VIDIOC_TRY_FMT32: 980 return put_v4l2_format32(parg, arg); 981 982 case VIDIOC_G_FBUF32: 983 return put_v4l2_framebuffer32(parg, arg); 984 #ifdef CONFIG_COMPAT_32BIT_TIME 985 case VIDIOC_QUERYBUF32_TIME32: 986 case VIDIOC_QBUF32_TIME32: 987 case VIDIOC_DQBUF32_TIME32: 988 case VIDIOC_PREPARE_BUF32_TIME32: 989 return put_v4l2_buffer32_time32(parg, arg); 990 #endif 991 case VIDIOC_QUERYBUF32: 992 case VIDIOC_QBUF32: 993 case VIDIOC_DQBUF32: 994 case VIDIOC_PREPARE_BUF32: 995 return put_v4l2_buffer32(parg, arg); 996 997 case VIDIOC_G_EXT_CTRLS32: 998 case VIDIOC_S_EXT_CTRLS32: 999 case VIDIOC_TRY_EXT_CTRLS32: 1000 return put_v4l2_ext_controls32(parg, arg); 1001 1002 case VIDIOC_CREATE_BUFS32: 1003 return put_v4l2_create32(parg, arg); 1004 1005 case VIDIOC_ENUMSTD32: 1006 return put_v4l2_standard32(parg, arg); 1007 1008 case VIDIOC_ENUMINPUT32: 1009 return put_v4l2_input32(parg, arg); 1010 1011 case VIDIOC_G_EDID32: 1012 case VIDIOC_S_EDID32: 1013 return put_v4l2_edid32(parg, arg); 1014 #ifdef CONFIG_X86_64 1015 case VIDIOC_DQEVENT32: 1016 return put_v4l2_event32(parg, arg); 1017 #endif 1018 #ifdef CONFIG_COMPAT_32BIT_TIME 1019 case VIDIOC_DQEVENT32_TIME32: 1020 return put_v4l2_event32_time32(parg, arg); 1021 #endif 1022 } 1023 return 0; 1024 } 1025 1026 int v4l2_compat_get_array_args(struct file *file, void *mbuf, 1027 void __user *user_ptr, size_t array_size, 1028 unsigned int cmd, void *arg) 1029 { 1030 int err = 0; 1031 1032 memset(mbuf, 0, array_size); 1033 1034 switch (cmd) { 1035 #ifdef CONFIG_COMPAT_32BIT_TIME 1036 case VIDIOC_QUERYBUF32_TIME32: 1037 case VIDIOC_QBUF32_TIME32: 1038 case VIDIOC_DQBUF32_TIME32: 1039 case VIDIOC_PREPARE_BUF32_TIME32: 1040 #endif 1041 case VIDIOC_QUERYBUF32: 1042 case VIDIOC_QBUF32: 1043 case VIDIOC_DQBUF32: 1044 case VIDIOC_PREPARE_BUF32: { 1045 struct v4l2_buffer *b64 = arg; 1046 struct v4l2_plane *p64 = mbuf; 1047 struct v4l2_plane32 __user *p32 = user_ptr; 1048 1049 if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) { 1050 u32 num_planes = b64->length; 1051 1052 if (num_planes == 0) 1053 return 0; 1054 1055 while (num_planes--) { 1056 err = get_v4l2_plane32(p64, p32, b64->memory); 1057 if (err) 1058 return err; 1059 ++p64; 1060 ++p32; 1061 } 1062 } 1063 break; 1064 } 1065 case VIDIOC_G_EXT_CTRLS32: 1066 case VIDIOC_S_EXT_CTRLS32: 1067 case VIDIOC_TRY_EXT_CTRLS32: { 1068 struct v4l2_ext_controls *ecs64 = arg; 1069 struct v4l2_ext_control *ec64 = mbuf; 1070 struct v4l2_ext_control32 __user *ec32 = user_ptr; 1071 int n; 1072 1073 for (n = 0; n < ecs64->count; n++) { 1074 if (copy_from_user(ec64, ec32, sizeof(*ec32))) 1075 return -EFAULT; 1076 1077 if (ctrl_is_pointer(file, ec64->id)) { 1078 compat_uptr_t p; 1079 1080 if (get_user(p, &ec32->string)) 1081 return -EFAULT; 1082 ec64->string = compat_ptr(p); 1083 } 1084 ec32++; 1085 ec64++; 1086 } 1087 break; 1088 } 1089 default: 1090 if (copy_from_user(mbuf, user_ptr, array_size)) 1091 err = -EFAULT; 1092 break; 1093 } 1094 1095 return err; 1096 } 1097 1098 int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr, 1099 void *mbuf, size_t array_size, 1100 unsigned int cmd, void *arg) 1101 { 1102 int err = 0; 1103 1104 switch (cmd) { 1105 #ifdef CONFIG_COMPAT_32BIT_TIME 1106 case VIDIOC_QUERYBUF32_TIME32: 1107 case VIDIOC_QBUF32_TIME32: 1108 case VIDIOC_DQBUF32_TIME32: 1109 case VIDIOC_PREPARE_BUF32_TIME32: 1110 #endif 1111 case VIDIOC_QUERYBUF32: 1112 case VIDIOC_QBUF32: 1113 case VIDIOC_DQBUF32: 1114 case VIDIOC_PREPARE_BUF32: { 1115 struct v4l2_buffer *b64 = arg; 1116 struct v4l2_plane *p64 = mbuf; 1117 struct v4l2_plane32 __user *p32 = user_ptr; 1118 1119 if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) { 1120 u32 num_planes = b64->length; 1121 1122 if (num_planes == 0) 1123 return 0; 1124 1125 while (num_planes--) { 1126 err = put_v4l2_plane32(p64, p32, b64->memory); 1127 if (err) 1128 return err; 1129 ++p64; 1130 ++p32; 1131 } 1132 } 1133 break; 1134 } 1135 case VIDIOC_G_EXT_CTRLS32: 1136 case VIDIOC_S_EXT_CTRLS32: 1137 case VIDIOC_TRY_EXT_CTRLS32: { 1138 struct v4l2_ext_controls *ecs64 = arg; 1139 struct v4l2_ext_control *ec64 = mbuf; 1140 struct v4l2_ext_control32 __user *ec32 = user_ptr; 1141 int n; 1142 1143 for (n = 0; n < ecs64->count; n++) { 1144 unsigned int size = sizeof(*ec32); 1145 /* 1146 * Do not modify the pointer when copying a pointer 1147 * control. The contents of the pointer was changed, 1148 * not the pointer itself. 1149 * The structures are otherwise compatible. 1150 */ 1151 if (ctrl_is_pointer(file, ec64->id)) 1152 size -= sizeof(ec32->value64); 1153 1154 if (copy_to_user(ec32, ec64, size)) 1155 return -EFAULT; 1156 1157 ec32++; 1158 ec64++; 1159 } 1160 break; 1161 } 1162 default: 1163 if (copy_to_user(user_ptr, mbuf, array_size)) 1164 err = -EFAULT; 1165 break; 1166 } 1167 1168 return err; 1169 } 1170 1171 /** 1172 * v4l2_compat_ioctl32() - Handles a compat32 ioctl call 1173 * 1174 * @file: pointer to &struct file with the file handler 1175 * @cmd: ioctl to be called 1176 * @arg: arguments passed from/to the ioctl handler 1177 * 1178 * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c 1179 * in order to deal with 32-bit calls on a 64-bits Kernel. 1180 * 1181 * This function calls do_video_ioctl() for non-private V4L2 ioctls. 1182 * If the function is a private one it calls vdev->fops->compat_ioctl32 1183 * instead. 1184 */ 1185 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) 1186 { 1187 struct video_device *vdev = video_devdata(file); 1188 long ret = -ENOIOCTLCMD; 1189 1190 if (!file->f_op->unlocked_ioctl) 1191 return ret; 1192 1193 if (!video_is_registered(vdev)) 1194 return -ENODEV; 1195 1196 if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) 1197 ret = file->f_op->unlocked_ioctl(file, cmd, 1198 (unsigned long)compat_ptr(arg)); 1199 else if (vdev->fops->compat_ioctl32) 1200 ret = vdev->fops->compat_ioctl32(file, cmd, arg); 1201 1202 if (ret == -ENOIOCTLCMD) 1203 pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", 1204 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); 1205 return ret; 1206 } 1207 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); 1208