* [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails
@ 2021-10-08 12:09 Ricardo Ribalda
2022-03-24 20:29 ` Laurent Pinchart
0 siblings, 1 reply; 4+ messages in thread
From: Ricardo Ribalda @ 2021-10-08 12:09 UTC (permalink / raw)
To: Laurent Pinchart, Mauro Carvalho Chehab, Hans Verkuil,
Ricardo Ribalda, linux-media, Colin King
If the mapping fails, the name field is not freed on exit.
Take the same approach as with the menu_info and have two different
allocations with two different life cycles.
Fixes: 07adedb5c606 ("media: uvcvideo: Use control names from framework")
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
To be applied after [PATCH][next] media: uvcvideo: Fix memory leak of object map on error exit path
Changelog v2: use kstrdup functions
drivers/media/usb/uvc/uvc_ctrl.c | 10 ++++++++++
drivers/media/usb/uvc/uvc_v4l2.c | 12 +++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 30bfe9069a1f..6bd7c30dfb75 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -2188,11 +2188,21 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
if (map == NULL)
return -ENOMEM;
+ /* For UVCIOC_CTRL_MAP custom controls */
+ if (mapping->name) {
+ map->name = kstrdup(mapping->name, GFP_KERNEL);
+ if (!map->name) {
+ kfree(map);
+ return -ENOMEM;
+ }
+ }
+
INIT_LIST_HEAD(&map->ev_subs);
size = sizeof(*mapping->menu_info) * mapping->menu_count;
map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
if (map->menu_info == NULL) {
+ kfree(map->name);
kfree(map);
return -ENOMEM;
}
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 711556d13d03..43bd8809241c 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -42,8 +42,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
map->id = xmap->id;
/* Non standard control id. */
if (v4l2_ctrl_get_name(map->id) == NULL) {
- map->name = kmemdup(xmap->name, sizeof(xmap->name),
- GFP_KERNEL);
+ map->name = kstrndup(xmap->name, sizeof(xmap->name),
+ GFP_KERNEL);
if (!map->name) {
ret = -ENOMEM;
goto free_map;
@@ -69,14 +69,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
if (xmap->menu_count == 0 ||
xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
ret = -EINVAL;
- goto free_map;
+ goto free_map_name;
}
size = xmap->menu_count * sizeof(*map->menu_info);
map->menu_info = memdup_user(xmap->menu_info, size);
if (IS_ERR(map->menu_info)) {
ret = PTR_ERR(map->menu_info);
- goto free_map;
+ goto free_map_name;
}
map->menu_count = xmap->menu_count;
@@ -86,12 +86,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
uvc_dbg(chain->dev, CONTROL,
"Unsupported V4L2 control type %u\n", xmap->v4l2_type);
ret = -ENOTTY;
- goto free_map;
+ goto free_map_name;
}
ret = uvc_ctrl_add_mapping(chain, map);
kfree(map->menu_info);
+free_map_name:
+ kfree(map->name);
free_map:
kfree(map);
--
2.33.0.882.g93a45727a2-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails
2021-10-08 12:09 [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails Ricardo Ribalda
@ 2022-03-24 20:29 ` Laurent Pinchart
2022-03-24 22:13 ` Ricardo Ribalda
0 siblings, 1 reply; 4+ messages in thread
From: Laurent Pinchart @ 2022-03-24 20:29 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, Colin King
Hi Ricardo,
Thank you for the patch.
On Fri, Oct 08, 2021 at 02:09:14PM +0200, Ricardo Ribalda wrote:
> If the mapping fails, the name field is not freed on exit.
> Take the same approach as with the menu_info and have two different
> allocations with two different life cycles.
>
> Fixes: 07adedb5c606 ("media: uvcvideo: Use control names from framework")
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> To be applied after [PATCH][next] media: uvcvideo: Fix memory leak of object map on error exit path
>
> Changelog v2: use kstrdup functions
>
> drivers/media/usb/uvc/uvc_ctrl.c | 10 ++++++++++
> drivers/media/usb/uvc/uvc_v4l2.c | 12 +++++++-----
> 2 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index 30bfe9069a1f..6bd7c30dfb75 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -2188,11 +2188,21 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
> if (map == NULL)
> return -ENOMEM;
>
> + /* For UVCIOC_CTRL_MAP custom controls */
> + if (mapping->name) {
> + map->name = kstrdup(mapping->name, GFP_KERNEL);
> + if (!map->name) {
> + kfree(map);
> + return -ENOMEM;
> + }
> + }
> +
> INIT_LIST_HEAD(&map->ev_subs);
>
> size = sizeof(*mapping->menu_info) * mapping->menu_count;
> map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
> if (map->menu_info == NULL) {
> + kfree(map->name);
> kfree(map);
> return -ENOMEM;
> }
Looks good to me.
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> index 711556d13d03..43bd8809241c 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -42,8 +42,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> map->id = xmap->id;
> /* Non standard control id. */
> if (v4l2_ctrl_get_name(map->id) == NULL) {
> - map->name = kmemdup(xmap->name, sizeof(xmap->name),
> - GFP_KERNEL);
> + map->name = kstrndup(xmap->name, sizeof(xmap->name),
> + GFP_KERNEL);
> if (!map->name) {
> ret = -ENOMEM;
> goto free_map;
But do we actually have to duplicate the name here, can't we set
map->name = xmap->name;
? We probably want to also set
xmap->name[sizeof(xmap->name) - 1] = '\0';
> @@ -69,14 +69,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> if (xmap->menu_count == 0 ||
> xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
> ret = -EINVAL;
> - goto free_map;
> + goto free_map_name;
> }
>
> size = xmap->menu_count * sizeof(*map->menu_info);
> map->menu_info = memdup_user(xmap->menu_info, size);
> if (IS_ERR(map->menu_info)) {
> ret = PTR_ERR(map->menu_info);
> - goto free_map;
> + goto free_map_name;
> }
>
> map->menu_count = xmap->menu_count;
> @@ -86,12 +86,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> uvc_dbg(chain->dev, CONTROL,
> "Unsupported V4L2 control type %u\n", xmap->v4l2_type);
> ret = -ENOTTY;
> - goto free_map;
> + goto free_map_name;
> }
>
> ret = uvc_ctrl_add_mapping(chain, map);
>
> kfree(map->menu_info);
> +free_map_name:
> + kfree(map->name);
> free_map:
> kfree(map);
>
> --
> 2.33.0.882.g93a45727a2-goog
>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails
2022-03-24 20:29 ` Laurent Pinchart
@ 2022-03-24 22:13 ` Ricardo Ribalda
2022-03-24 22:21 ` Laurent Pinchart
0 siblings, 1 reply; 4+ messages in thread
From: Ricardo Ribalda @ 2022-03-24 22:13 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, Colin King
Hi Laurent
Thanks for your review
On Thu, 24 Mar 2022 at 21:29, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Ricardo,
>
> Thank you for the patch.
>
> On Fri, Oct 08, 2021 at 02:09:14PM +0200, Ricardo Ribalda wrote:
> > If the mapping fails, the name field is not freed on exit.
> > Take the same approach as with the menu_info and have two different
> > allocations with two different life cycles.
> >
> > Fixes: 07adedb5c606 ("media: uvcvideo: Use control names from framework")
> > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> > ---
> > To be applied after [PATCH][next] media: uvcvideo: Fix memory leak of object map on error exit path
> >
> > Changelog v2: use kstrdup functions
> >
> > drivers/media/usb/uvc/uvc_ctrl.c | 10 ++++++++++
> > drivers/media/usb/uvc/uvc_v4l2.c | 12 +++++++-----
> > 2 files changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> > index 30bfe9069a1f..6bd7c30dfb75 100644
> > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > @@ -2188,11 +2188,21 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
> > if (map == NULL)
> > return -ENOMEM;
> >
> > + /* For UVCIOC_CTRL_MAP custom controls */
> > + if (mapping->name) {
> > + map->name = kstrdup(mapping->name, GFP_KERNEL);
> > + if (!map->name) {
> > + kfree(map);
> > + return -ENOMEM;
> > + }
> > + }
> > +
> > INIT_LIST_HEAD(&map->ev_subs);
> >
> > size = sizeof(*mapping->menu_info) * mapping->menu_count;
> > map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
> > if (map->menu_info == NULL) {
> > + kfree(map->name);
> > kfree(map);
> > return -ENOMEM;
> > }
>
> Looks good to me.
>
> > diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> > index 711556d13d03..43bd8809241c 100644
> > --- a/drivers/media/usb/uvc/uvc_v4l2.c
> > +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> > @@ -42,8 +42,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > map->id = xmap->id;
> > /* Non standard control id. */
> > if (v4l2_ctrl_get_name(map->id) == NULL) {
> > - map->name = kmemdup(xmap->name, sizeof(xmap->name),
> > - GFP_KERNEL);
> > + map->name = kstrndup(xmap->name, sizeof(xmap->name),
> > + GFP_KERNEL);
> > if (!map->name) {
> > ret = -ENOMEM;
> > goto free_map;
>
> But do we actually have to duplicate the name here, can't we set
>
> map->name = xmap->name;
>
> ? We probably want to also set
>
> xmap->name[sizeof(xmap->name) - 1] = '\0';
Can we securely do this? xmap comes from the ioctl. I was trying to
avoid writing to user without put_user()
Thanks
>
> > @@ -69,14 +69,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > if (xmap->menu_count == 0 ||
> > xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
> > ret = -EINVAL;
> > - goto free_map;
> > + goto free_map_name;
> > }
> >
> > size = xmap->menu_count * sizeof(*map->menu_info);
> > map->menu_info = memdup_user(xmap->menu_info, size);
> > if (IS_ERR(map->menu_info)) {
> > ret = PTR_ERR(map->menu_info);
> > - goto free_map;
> > + goto free_map_name;
> > }
> >
> > map->menu_count = xmap->menu_count;
> > @@ -86,12 +86,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > uvc_dbg(chain->dev, CONTROL,
> > "Unsupported V4L2 control type %u\n", xmap->v4l2_type);
> > ret = -ENOTTY;
> > - goto free_map;
> > + goto free_map_name;
> > }
> >
> > ret = uvc_ctrl_add_mapping(chain, map);
> >
> > kfree(map->menu_info);
> > +free_map_name:
> > + kfree(map->name);
> > free_map:
> > kfree(map);
> >
> > --
> > 2.33.0.882.g93a45727a2-goog
> >
>
> --
> Regards,
>
> Laurent Pinchart
--
Ricardo Ribalda
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails
2022-03-24 22:13 ` Ricardo Ribalda
@ 2022-03-24 22:21 ` Laurent Pinchart
0 siblings, 0 replies; 4+ messages in thread
From: Laurent Pinchart @ 2022-03-24 22:21 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, Colin King
Hi Ricardo,
On Thu, Mar 24, 2022 at 11:13:14PM +0100, Ricardo Ribalda wrote:
> On Thu, 24 Mar 2022 at 21:29, Laurent Pinchart wrote:
> > On Fri, Oct 08, 2021 at 02:09:14PM +0200, Ricardo Ribalda wrote:
> > > If the mapping fails, the name field is not freed on exit.
> > > Take the same approach as with the menu_info and have two different
> > > allocations with two different life cycles.
> > >
> > > Fixes: 07adedb5c606 ("media: uvcvideo: Use control names from framework")
> > > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> > > ---
> > > To be applied after [PATCH][next] media: uvcvideo: Fix memory leak of object map on error exit path
> > >
> > > Changelog v2: use kstrdup functions
> > >
> > > drivers/media/usb/uvc/uvc_ctrl.c | 10 ++++++++++
> > > drivers/media/usb/uvc/uvc_v4l2.c | 12 +++++++-----
> > > 2 files changed, 17 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> > > index 30bfe9069a1f..6bd7c30dfb75 100644
> > > --- a/drivers/media/usb/uvc/uvc_ctrl.c
> > > +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> > > @@ -2188,11 +2188,21 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
> > > if (map == NULL)
> > > return -ENOMEM;
> > >
> > > + /* For UVCIOC_CTRL_MAP custom controls */
> > > + if (mapping->name) {
> > > + map->name = kstrdup(mapping->name, GFP_KERNEL);
> > > + if (!map->name) {
> > > + kfree(map);
> > > + return -ENOMEM;
> > > + }
> > > + }
> > > +
> > > INIT_LIST_HEAD(&map->ev_subs);
> > >
> > > size = sizeof(*mapping->menu_info) * mapping->menu_count;
> > > map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
> > > if (map->menu_info == NULL) {
> > > + kfree(map->name);
> > > kfree(map);
> > > return -ENOMEM;
> > > }
> >
> > Looks good to me.
> >
> > > diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> > > index 711556d13d03..43bd8809241c 100644
> > > --- a/drivers/media/usb/uvc/uvc_v4l2.c
> > > +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> > > @@ -42,8 +42,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > > map->id = xmap->id;
> > > /* Non standard control id. */
> > > if (v4l2_ctrl_get_name(map->id) == NULL) {
> > > - map->name = kmemdup(xmap->name, sizeof(xmap->name),
> > > - GFP_KERNEL);
> > > + map->name = kstrndup(xmap->name, sizeof(xmap->name),
> > > + GFP_KERNEL);
> > > if (!map->name) {
> > > ret = -ENOMEM;
> > > goto free_map;
> >
> > But do we actually have to duplicate the name here, can't we set
> >
> > map->name = xmap->name;
> >
> > ? We probably want to also set
> >
> > xmap->name[sizeof(xmap->name) - 1] = '\0';
>
> Can we securely do this? xmap comes from the ioctl. I was trying to
> avoid writing to user without put_user()
xmap has gone through video_ioctl2(), it's not a __user pointer anymore.
Only memory that xmap fields point to (such as menu_info) is user
memory.
> > > @@ -69,14 +69,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > > if (xmap->menu_count == 0 ||
> > > xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
> > > ret = -EINVAL;
> > > - goto free_map;
> > > + goto free_map_name;
> > > }
> > >
> > > size = xmap->menu_count * sizeof(*map->menu_info);
> > > map->menu_info = memdup_user(xmap->menu_info, size);
> > > if (IS_ERR(map->menu_info)) {
> > > ret = PTR_ERR(map->menu_info);
> > > - goto free_map;
> > > + goto free_map_name;
> > > }
> > >
> > > map->menu_count = xmap->menu_count;
> > > @@ -86,12 +86,14 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
> > > uvc_dbg(chain->dev, CONTROL,
> > > "Unsupported V4L2 control type %u\n", xmap->v4l2_type);
> > > ret = -ENOTTY;
> > > - goto free_map;
> > > + goto free_map_name;
> > > }
> > >
> > > ret = uvc_ctrl_add_mapping(chain, map);
> > >
> > > kfree(map->menu_info);
> > > +free_map_name:
> > > + kfree(map->name);
> > > free_map:
> > > kfree(map);
> > >
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-03-24 22:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-08 12:09 [PATCH v2] media: uvcvideo: Fix memory leak if uvc_ctrl_add_mapping fails Ricardo Ribalda
2022-03-24 20:29 ` Laurent Pinchart
2022-03-24 22:13 ` Ricardo Ribalda
2022-03-24 22:21 ` Laurent Pinchart
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).