aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMartin Rubli <martin_rubli@logitech.com>2010-09-08 03:15:23 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:18:22 -0400
commit8fb91b33c6bfa3ac5e4ad76920b7bcd7bdbbb6d0 (patch)
treec7e33ca829580a6a8d8f8808c4b860cf12a2cbca /drivers
parentba2fa99668bb9bf03757a020f15bba295d5c0a3e (diff)
[media] uvcvideo: Remove sysadmin requirements for UVCIOC_CTRL_MAP
This patch removes the sysadmin requirements for UVCIOC_CTRL_MAP (and the stub implementation of UVCIOC_CTRL_ADD). This requirement no longer makes sense with the new XU control access mechanisms since XU controls can be accessed without adding control mappings first. A maximum number (currently 1024) of control mappings per device is enforced to avoid excess memory consumption caused by careless user space applications. Signed-off-by: Martin Rubli <martin_rubli@logitech.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c14
-rw-r--r--drivers/media/video/uvc/uvc_driver.c1
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c6
-rw-r--r--drivers/media/video/uvc/uvcvideo.h4
4 files changed, 19 insertions, 6 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 2c81b7f35551..531a3e1a6d17 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1435,6 +1435,7 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
1435 struct uvc_entity *entity; 1435 struct uvc_entity *entity;
1436 struct uvc_control *ctrl; 1436 struct uvc_control *ctrl;
1437 int found = 0; 1437 int found = 0;
1438 int ret;
1438 1439
1439 if (mapping->id & ~V4L2_CTRL_ID_MASK) { 1440 if (mapping->id & ~V4L2_CTRL_ID_MASK) {
1440 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', control " 1441 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', control "
@@ -1478,7 +1479,20 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
1478 } 1479 }
1479 } 1480 }
1480 1481
1482 /* Prevent excess memory consumption */
1483 if (atomic_inc_return(&dev->nmappings) > UVC_MAX_CONTROL_MAPPINGS) {
1484 atomic_dec(&dev->nmappings);
1485 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', maximum "
1486 "mappings count (%u) exceeded.\n", mapping->name,
1487 UVC_MAX_CONTROL_MAPPINGS);
1488 ret = -ENOMEM;
1489 goto done;
1490 }
1491
1481 ret = __uvc_ctrl_add_mapping(dev, ctrl, mapping); 1492 ret = __uvc_ctrl_add_mapping(dev, ctrl, mapping);
1493 if (ret < 0)
1494 atomic_dec(&dev->nmappings);
1495
1482done: 1496done:
1483 mutex_unlock(&chain->ctrl_mutex); 1497 mutex_unlock(&chain->ctrl_mutex);
1484 return ret; 1498 return ret;
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 71efda76cc73..a1e9dfb52f69 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1760,6 +1760,7 @@ static int uvc_probe(struct usb_interface *intf,
1760 INIT_LIST_HEAD(&dev->streams); 1760 INIT_LIST_HEAD(&dev->streams);
1761 atomic_set(&dev->nstreams, 0); 1761 atomic_set(&dev->nstreams, 0);
1762 atomic_set(&dev->users, 0); 1762 atomic_set(&dev->users, 0);
1763 atomic_set(&dev->nmappings, 0);
1763 1764
1764 dev->udev = usb_get_dev(udev); 1765 dev->udev = usb_get_dev(udev);
1765 dev->intf = usb_get_intf(intf); 1766 dev->intf = usb_get_intf(intf);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 4a510483f7c5..6d15de9b5204 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1025,16 +1025,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1025 /* Dynamic controls. */ 1025 /* Dynamic controls. */
1026 case UVCIOC_CTRL_ADD: 1026 case UVCIOC_CTRL_ADD:
1027 /* Legacy ioctl, kept for API compatibility reasons */ 1027 /* Legacy ioctl, kept for API compatibility reasons */
1028 if (!capable(CAP_SYS_ADMIN))
1029 return -EPERM;
1030
1031 return -EEXIST; 1028 return -EEXIST;
1032 1029
1033 case UVCIOC_CTRL_MAP_OLD: 1030 case UVCIOC_CTRL_MAP_OLD:
1034 case UVCIOC_CTRL_MAP: 1031 case UVCIOC_CTRL_MAP:
1035 if (!capable(CAP_SYS_ADMIN))
1036 return -EPERM;
1037
1038 return uvc_ioctl_ctrl_map(chain, arg, 1032 return uvc_ioctl_ctrl_map(chain, arg,
1039 cmd == UVCIOC_CTRL_MAP_OLD); 1033 cmd == UVCIOC_CTRL_MAP_OLD);
1040 1034
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 34637fbbbd61..39e9e36e8839 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -172,6 +172,9 @@ struct uvc_xu_control {
172#define UVC_CTRL_CONTROL_TIMEOUT 300 172#define UVC_CTRL_CONTROL_TIMEOUT 300
173#define UVC_CTRL_STREAMING_TIMEOUT 5000 173#define UVC_CTRL_STREAMING_TIMEOUT 5000
174 174
175/* Maximum allowed number of control mappings per device */
176#define UVC_MAX_CONTROL_MAPPINGS 1024
177
175/* Devices quirks */ 178/* Devices quirks */
176#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 179#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
177#define UVC_QUIRK_PROBE_MINMAX 0x00000002 180#define UVC_QUIRK_PROBE_MINMAX 0x00000002
@@ -472,6 +475,7 @@ struct uvc_device {
472 475
473 enum uvc_device_state state; 476 enum uvc_device_state state;
474 atomic_t users; 477 atomic_t users;
478 atomic_t nmappings;
475 479
476 /* Video control interface */ 480 /* Video control interface */
477 __u16 uvc_version; 481 __u16 uvc_version;