diff options
author | Martin Rubli <martin_rubli@logitech.com> | 2010-09-08 03:15:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:18:22 -0400 |
commit | 8fb91b33c6bfa3ac5e4ad76920b7bcd7bdbbb6d0 (patch) | |
tree | c7e33ca829580a6a8d8f8808c4b860cf12a2cbca /drivers | |
parent | ba2fa99668bb9bf03757a020f15bba295d5c0a3e (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.c | 14 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_v4l2.c | 6 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 4 |
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 | |||
1482 | done: | 1496 | done: |
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; |