Commit c6abf81a authored by Hans Verkuil's avatar Hans Verkuil Committed by Lipeng Sang
Browse files

media: vivid: dev->bitmap_cap wasn't freed in all cases

stable inclusion
from stable-v5.10.153
commit 147b8f1892aaa474f912ac75babfd316ee0de672
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I64YCA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=147b8f1892aaa474f912ac75babfd316ee0de672



--------------------------------

[ Upstream commit 1f65ea41 ]

Whenever the compose width/height values change, the dev->bitmap_cap
vmalloc'ed array must be freed and dev->bitmap_cap set to NULL.

This was done in some places, but not all. This is only an issue if
overlay support is enabled and the bitmap clipping is used.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: ef834f78 ([media] vivid: add the video capture and output parts)
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarLipeng Sang <sanglipeng1@jd.com>
parent a388caac
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -452,6 +452,12 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
	tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
	dev->crop_cap = dev->src_rect;
	dev->crop_bounds_cap = dev->src_rect;
	if (dev->bitmap_cap &&
	    (dev->compose_cap.width != dev->crop_cap.width ||
	     dev->compose_cap.height != dev->crop_cap.height)) {
		vfree(dev->bitmap_cap);
		dev->bitmap_cap = NULL;
	}
	dev->compose_cap = dev->crop_cap;
	if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
		dev->compose_cap.height /= 2;
@@ -909,6 +915,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
	struct vivid_dev *dev = video_drvdata(file);
	struct v4l2_rect *crop = &dev->crop_cap;
	struct v4l2_rect *compose = &dev->compose_cap;
	unsigned orig_compose_w = compose->width;
	unsigned orig_compose_h = compose->height;
	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
	int ret;

@@ -1026,17 +1034,17 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
			s->r.height /= factor;
		}
		v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
		if (dev->bitmap_cap && (compose->width != s->r.width ||
					compose->height != s->r.height)) {
			vfree(dev->bitmap_cap);
			dev->bitmap_cap = NULL;
		}
		*compose = s->r;
		break;
	default:
		return -EINVAL;
	}

	if (dev->bitmap_cap && (compose->width != orig_compose_w ||
				compose->height != orig_compose_h)) {
		vfree(dev->bitmap_cap);
		dev->bitmap_cap = NULL;
	}
	tpg_s_crop_compose(&dev->tpg, crop, compose);
	return 0;
}