aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/uvc
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2016-07-08 17:14:03 -0400
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-07-08 17:14:03 -0400
commitfb810cb5eda8c47e3afbb45ea6b9676841d29e8d (patch)
tree618af9a957c6744e59d0183619a2e6cbbf685233 /drivers/media/usb/uvc
parent241d9bb3427e1d074daa864a65730412b9a47a39 (diff)
parenta99cde438de0c4c0cecc1d1af1a55a75b10bfdef (diff)
Merge tag 'v4.7-rc6' into patchwork
Linux 4.7-rc6 * tag 'v4.7-rc6': (1245 commits) Linux 4.7-rc6 ovl: warn instead of error if d_type is not supported MIPS: Fix possible corruption of cache mode by mprotect. locks: use file_inode() usb: dwc3: st: Use explicit reset_control_get_exclusive() API phy: phy-stih407-usb: Use explicit reset_control_get_exclusive() API phy: miphy28lp: Inform the reset framework that our reset line may be shared namespace: update event counter when umounting a deleted dentry 9p: use file_dentry() lockd: unregister notifier blocks if the service fails to come up completely ACPI,PCI,IRQ: correct operator precedence fuse: serialize dirops by default drm/i915: Fix missing unlock on error in i915_ppgtt_info() powerpc: Initialise pci_io_base as early as possible mfd: da9053: Fix compiler warning message for uninitialised variable mfd: max77620: Fix FPS switch statements phy: phy-stih407-usb: Inform the reset framework that our reset line may be shared usb: dwc3: st: Inform the reset framework that our reset line may be shared usb: host: ehci-st: Inform the reset framework that our reset line may be shared usb: host: ohci-st: Inform the reset framework that our reset line may be shared ...
Diffstat (limited to 'drivers/media/usb/uvc')
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c97
1 files changed, 20 insertions, 77 deletions
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index cded5ef52e24..05eed4be25df 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -1289,8 +1289,6 @@ struct uvc_xu_control_mapping32 {
1289static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, 1289static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1290 const struct uvc_xu_control_mapping32 __user *up) 1290 const struct uvc_xu_control_mapping32 __user *up)
1291{ 1291{
1292 struct uvc_menu_info __user *umenus;
1293 struct uvc_menu_info __user *kmenus;
1294 compat_caddr_t p; 1292 compat_caddr_t p;
1295 1293
1296 if (!access_ok(VERIFY_READ, up, sizeof(*up)) || 1294 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
@@ -1307,17 +1305,7 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1307 1305
1308 if (__get_user(p, &up->menu_info)) 1306 if (__get_user(p, &up->menu_info))
1309 return -EFAULT; 1307 return -EFAULT;
1310 umenus = compat_ptr(p); 1308 kp->menu_info = compat_ptr(p);
1311 if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
1312 return -EFAULT;
1313
1314 kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
1315 if (kmenus == NULL)
1316 return -EFAULT;
1317 kp->menu_info = kmenus;
1318
1319 if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
1320 return -EFAULT;
1321 1309
1322 return 0; 1310 return 0;
1323} 1311}
@@ -1325,10 +1313,6 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1325static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, 1313static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1326 struct uvc_xu_control_mapping32 __user *up) 1314 struct uvc_xu_control_mapping32 __user *up)
1327{ 1315{
1328 struct uvc_menu_info __user *umenus;
1329 struct uvc_menu_info __user *kmenus = kp->menu_info;
1330 compat_caddr_t p;
1331
1332 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || 1316 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1333 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) || 1317 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1334 __put_user(kp->menu_count, &up->menu_count)) 1318 __put_user(kp->menu_count, &up->menu_count))
@@ -1337,16 +1321,6 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1337 if (__clear_user(up->reserved, sizeof(up->reserved))) 1321 if (__clear_user(up->reserved, sizeof(up->reserved)))
1338 return -EFAULT; 1322 return -EFAULT;
1339 1323
1340 if (kp->menu_count == 0)
1341 return 0;
1342
1343 if (get_user(p, &up->menu_info))
1344 return -EFAULT;
1345 umenus = compat_ptr(p);
1346
1347 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1348 return -EFAULT;
1349
1350 return 0; 1324 return 0;
1351} 1325}
1352 1326
@@ -1361,8 +1335,6 @@ struct uvc_xu_control_query32 {
1361static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, 1335static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1362 const struct uvc_xu_control_query32 __user *up) 1336 const struct uvc_xu_control_query32 __user *up)
1363{ 1337{
1364 u8 __user *udata;
1365 u8 __user *kdata;
1366 compat_caddr_t p; 1338 compat_caddr_t p;
1367 1339
1368 if (!access_ok(VERIFY_READ, up, sizeof(*up)) || 1340 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
@@ -1376,17 +1348,7 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1376 1348
1377 if (__get_user(p, &up->data)) 1349 if (__get_user(p, &up->data))
1378 return -EFAULT; 1350 return -EFAULT;
1379 udata = compat_ptr(p); 1351 kp->data = compat_ptr(p);
1380 if (!access_ok(VERIFY_READ, udata, kp->size))
1381 return -EFAULT;
1382
1383 kdata = compat_alloc_user_space(kp->size);
1384 if (kdata == NULL)
1385 return -EFAULT;
1386 kp->data = kdata;
1387
1388 if (copy_in_user(kdata, udata, kp->size))
1389 return -EFAULT;
1390 1352
1391 return 0; 1353 return 0;
1392} 1354}
@@ -1394,26 +1356,10 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1394static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, 1356static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1395 struct uvc_xu_control_query32 __user *up) 1357 struct uvc_xu_control_query32 __user *up)
1396{ 1358{
1397 u8 __user *udata;
1398 u8 __user *kdata = kp->data;
1399 compat_caddr_t p;
1400
1401 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || 1359 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1402 __copy_to_user(up, kp, offsetof(typeof(*up), data))) 1360 __copy_to_user(up, kp, offsetof(typeof(*up), data)))
1403 return -EFAULT; 1361 return -EFAULT;
1404 1362
1405 if (kp->size == 0)
1406 return 0;
1407
1408 if (get_user(p, &up->data))
1409 return -EFAULT;
1410 udata = compat_ptr(p);
1411 if (!access_ok(VERIFY_READ, udata, kp->size))
1412 return -EFAULT;
1413
1414 if (copy_in_user(udata, kdata, kp->size))
1415 return -EFAULT;
1416
1417 return 0; 1363 return 0;
1418} 1364}
1419 1365
@@ -1423,47 +1369,44 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1423static long uvc_v4l2_compat_ioctl32(struct file *file, 1369static long uvc_v4l2_compat_ioctl32(struct file *file,
1424 unsigned int cmd, unsigned long arg) 1370 unsigned int cmd, unsigned long arg)
1425{ 1371{
1372 struct uvc_fh *handle = file->private_data;
1426 union { 1373 union {
1427 struct uvc_xu_control_mapping xmap; 1374 struct uvc_xu_control_mapping xmap;
1428 struct uvc_xu_control_query xqry; 1375 struct uvc_xu_control_query xqry;
1429 } karg; 1376 } karg;
1430 void __user *up = compat_ptr(arg); 1377 void __user *up = compat_ptr(arg);
1431 mm_segment_t old_fs;
1432 long ret; 1378 long ret;
1433 1379
1434 switch (cmd) { 1380 switch (cmd) {
1435 case UVCIOC_CTRL_MAP32: 1381 case UVCIOC_CTRL_MAP32:
1436 cmd = UVCIOC_CTRL_MAP;
1437 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up); 1382 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1383 if (ret)
1384 return ret;
1385 ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
1386 if (ret)
1387 return ret;
1388 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1389 if (ret)
1390 return ret;
1391
1438 break; 1392 break;
1439 1393
1440 case UVCIOC_CTRL_QUERY32: 1394 case UVCIOC_CTRL_QUERY32:
1441 cmd = UVCIOC_CTRL_QUERY;
1442 ret = uvc_v4l2_get_xu_query(&karg.xqry, up); 1395 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1396 if (ret)
1397 return ret;
1398 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1399 if (ret)
1400 return ret;
1401 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1402 if (ret)
1403 return ret;
1443 break; 1404 break;
1444 1405
1445 default: 1406 default:
1446 return -ENOIOCTLCMD; 1407 return -ENOIOCTLCMD;
1447 } 1408 }
1448 1409
1449 old_fs = get_fs();
1450 set_fs(KERNEL_DS);
1451 ret = video_ioctl2(file, cmd, (unsigned long)&karg);
1452 set_fs(old_fs);
1453
1454 if (ret < 0)
1455 return ret;
1456
1457 switch (cmd) {
1458 case UVCIOC_CTRL_MAP:
1459 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1460 break;
1461
1462 case UVCIOC_CTRL_QUERY:
1463 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1464 break;
1465 }
1466
1467 return ret; 1410 return ret;
1468} 1411}
1469#endif 1412#endif