Commit 1bcd7041 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] s5p-fimc: Don't allocate fimc-lite video device structure dynamically

This fixes potential invalid pointer de-reference, when
media_entity_cleanup() is called after video_unregister_device,
and video device structure memory is already freed.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8cf5e2a9
...@@ -137,7 +137,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) ...@@ -137,7 +137,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
} }
if (i == 0 && src_pixfmt_map[i][0] != pixelcode) { if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
v4l2_err(dev->vfd, v4l2_err(&dev->vfd,
"Unsupported pixel code, falling back to %#08x\n", "Unsupported pixel code, falling back to %#08x\n",
src_pixfmt_map[i][0]); src_pixfmt_map[i][0]);
} }
......
...@@ -374,7 +374,7 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -374,7 +374,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
unsigned long size = fimc->payload[i]; unsigned long size = fimc->payload[i];
if (vb2_plane_size(vb, i) < size) { if (vb2_plane_size(vb, i) < size) {
v4l2_err(fimc->vfd, v4l2_err(&fimc->vfd,
"User buffer too small (%ld < %ld)\n", "User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size); vb2_plane_size(vb, i), size);
return -EINVAL; return -EINVAL;
...@@ -467,7 +467,7 @@ static int fimc_lite_open(struct file *file) ...@@ -467,7 +467,7 @@ static int fimc_lite_open(struct file *file)
if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
ret = fimc_pipeline_initialize(&fimc->pipeline, ret = fimc_pipeline_initialize(&fimc->pipeline,
&fimc->vfd->entity, true); &fimc->vfd.entity, true);
if (ret < 0) { if (ret < 0) {
pm_runtime_put_sync(&fimc->pdev->dev); pm_runtime_put_sync(&fimc->pdev->dev);
fimc->ref_count--; fimc->ref_count--;
...@@ -1215,18 +1215,14 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) ...@@ -1215,18 +1215,14 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
{ {
struct fimc_lite *fimc = v4l2_get_subdevdata(sd); struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
struct vb2_queue *q = &fimc->vb_queue; struct vb2_queue *q = &fimc->vb_queue;
struct video_device *vfd; struct video_device *vfd = &fimc->vfd;
int ret; int ret;
memset(vfd, 0, sizeof(*vfd));
fimc->fmt = &fimc_lite_formats[0]; fimc->fmt = &fimc_lite_formats[0];
fimc->out_path = FIMC_IO_DMA; fimc->out_path = FIMC_IO_DMA;
vfd = video_device_alloc();
if (!vfd) {
v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
return -ENOMEM;
}
snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture", snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
fimc->index); fimc->index);
...@@ -1234,9 +1230,8 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) ...@@ -1234,9 +1230,8 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
vfd->ioctl_ops = &fimc_lite_ioctl_ops; vfd->ioctl_ops = &fimc_lite_ioctl_ops;
vfd->v4l2_dev = sd->v4l2_dev; vfd->v4l2_dev = sd->v4l2_dev;
vfd->minor = -1; vfd->minor = -1;
vfd->release = video_device_release; vfd->release = video_device_release_empty;
vfd->lock = &fimc->lock; vfd->lock = &fimc->lock;
fimc->vfd = vfd;
fimc->ref_count = 0; fimc->ref_count = 0;
fimc->reqbufs_count = 0; fimc->reqbufs_count = 0;
...@@ -1255,24 +1250,20 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) ...@@ -1255,24 +1250,20 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
if (ret) if (ret < 0)
goto err; return ret;
video_set_drvdata(vfd, fimc); video_set_drvdata(vfd, fimc);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret) if (ret < 0) {
goto err_vd; media_entity_cleanup(&vfd->entity);
return ret;
}
v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n", v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd)); vfd->name, video_device_node_name(vfd));
return 0; return 0;
err_vd:
media_entity_cleanup(&vfd->entity);
err:
video_device_release(vfd);
return ret;
} }
static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
...@@ -1282,10 +1273,9 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) ...@@ -1282,10 +1273,9 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
if (fimc == NULL) if (fimc == NULL)
return; return;
if (fimc->vfd) { if (video_is_registered(&fimc->vfd)) {
video_unregister_device(fimc->vfd); video_unregister_device(&fimc->vfd);
media_entity_cleanup(&fimc->vfd->entity); media_entity_cleanup(&fimc->vfd.entity);
fimc->vfd = NULL;
} }
} }
...@@ -1515,7 +1505,7 @@ static int fimc_lite_resume(struct device *dev) ...@@ -1515,7 +1505,7 @@ static int fimc_lite_resume(struct device *dev)
return 0; return 0;
INIT_LIST_HEAD(&fimc->active_buf_q); INIT_LIST_HEAD(&fimc->active_buf_q);
fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false); fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd.entity, false);
fimc_lite_hw_init(fimc); fimc_lite_hw_init(fimc);
clear_bit(ST_FLITE_SUSPENDED, &fimc->state); clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
......
...@@ -132,7 +132,7 @@ struct fimc_lite { ...@@ -132,7 +132,7 @@ struct fimc_lite {
struct platform_device *pdev; struct platform_device *pdev;
struct flite_variant *variant; struct flite_variant *variant;
struct v4l2_device *v4l2_dev; struct v4l2_device *v4l2_dev;
struct video_device *vfd; struct video_device vfd;
struct v4l2_fh fh; struct v4l2_fh fh;
struct vb2_alloc_ctx *alloc_ctx; struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev; struct v4l2_subdev subdev;
......
...@@ -591,7 +591,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd) ...@@ -591,7 +591,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
if (fimc == NULL) if (fimc == NULL)
continue; continue;
source = &fimc->subdev.entity; source = &fimc->subdev.entity;
sink = &fimc->vfd->entity; sink = &fimc->vfd.entity;
/* FIMC-LITE's subdev and video node */ /* FIMC-LITE's subdev and video node */
ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
sink, 0, flags); sink, 0, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment