Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8269ab16 authored by Zhipeng Lu's avatar Zhipeng Lu Committed by Sasha Levin
Browse files

media: v4l2-tpg: fix some memleaks in tpg_alloc



[ Upstream commit 8cf9c5051076e0eb958f4361d50d8b0c3ee6691c ]

In tpg_alloc, resources should be deallocated in each and every
error-handling paths, since they are allocated in for statements.
Otherwise there would be memleaks because tpg_free is called only when
tpg_alloc return 0.

Fixes: 63881df9 ("[media] vivid: add the Test Pattern Generator")
Signed-off-by: default avatarZhipeng Lu <alexious@zju.edu.cn>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 2e6892b2
Loading
Loading
Loading
Loading
+42 −10
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
{
	unsigned pat;
	unsigned plane;
	int ret = 0;

	tpg->max_line_width = max_w;
	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
@@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)

			tpg->lines[pat][plane] =
				vzalloc(array3_size(max_w, 2, pixelsz));
			if (!tpg->lines[pat][plane])
				return -ENOMEM;
			if (!tpg->lines[pat][plane]) {
				ret = -ENOMEM;
				goto free_lines;
			}
			if (plane == 0)
				continue;
			tpg->downsampled_lines[pat][plane] =
				vzalloc(array3_size(max_w, 2, pixelsz));
			if (!tpg->downsampled_lines[pat][plane])
				return -ENOMEM;
			if (!tpg->downsampled_lines[pat][plane]) {
				ret = -ENOMEM;
				goto free_lines;
			}
		}
	}
	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)

		tpg->contrast_line[plane] =
			vzalloc(array_size(pixelsz, max_w));
		if (!tpg->contrast_line[plane])
			return -ENOMEM;
		if (!tpg->contrast_line[plane]) {
			ret = -ENOMEM;
			goto free_contrast_line;
		}
		tpg->black_line[plane] =
			vzalloc(array_size(pixelsz, max_w));
		if (!tpg->black_line[plane])
			return -ENOMEM;
		if (!tpg->black_line[plane]) {
			ret = -ENOMEM;
			goto free_contrast_line;
		}
		tpg->random_line[plane] =
			vzalloc(array3_size(max_w, 2, pixelsz));
		if (!tpg->random_line[plane])
			return -ENOMEM;
		if (!tpg->random_line[plane]) {
			ret = -ENOMEM;
			goto free_contrast_line;
		}
	}
	return 0;

free_contrast_line:
	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
		vfree(tpg->contrast_line[plane]);
		vfree(tpg->black_line[plane]);
		vfree(tpg->random_line[plane]);
		tpg->contrast_line[plane] = NULL;
		tpg->black_line[plane] = NULL;
		tpg->random_line[plane] = NULL;
	}
free_lines:
	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
			vfree(tpg->lines[pat][plane]);
			tpg->lines[pat][plane] = NULL;
			if (plane == 0)
				continue;
			vfree(tpg->downsampled_lines[pat][plane]);
			tpg->downsampled_lines[pat][plane] = NULL;
		}
	return ret;
}
EXPORT_SYMBOL_GPL(tpg_alloc);