1 From a57175d953bcd5d50f0bff8f4326af176c56f2d5 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Thu, 1 Feb 2024 20:47:53 +0800
4 Subject: media: v4l2-tpg: fix some memleaks in tpg_alloc
6 From: Zhipeng Lu <alexious@zju.edu.cn>
8 [ Upstream commit 8cf9c5051076e0eb958f4361d50d8b0c3ee6691c ]
10 In tpg_alloc, resources should be deallocated in each and every
11 error-handling paths, since they are allocated in for statements.
12 Otherwise there would be memleaks because tpg_free is called only when
15 Fixes: 63881df94d3e ("[media] vivid: add the Test Pattern Generator")
16 Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
17 Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
18 Signed-off-by: Sasha Levin <sashal@kernel.org>
20 drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 52 +++++++++++++++----
21 1 file changed, 42 insertions(+), 10 deletions(-)
23 diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
24 index a366566f22c3b..642c48e8c1f58 100644
25 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
26 +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
27 @@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
33 tpg->max_line_width = max_w;
34 for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
35 @@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
37 tpg->lines[pat][plane] =
38 vzalloc(array3_size(max_w, 2, pixelsz));
39 - if (!tpg->lines[pat][plane])
41 + if (!tpg->lines[pat][plane]) {
47 tpg->downsampled_lines[pat][plane] =
48 vzalloc(array3_size(max_w, 2, pixelsz));
49 - if (!tpg->downsampled_lines[pat][plane])
51 + if (!tpg->downsampled_lines[pat][plane]) {
57 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
58 @@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
60 tpg->contrast_line[plane] =
61 vzalloc(array_size(pixelsz, max_w));
62 - if (!tpg->contrast_line[plane])
64 + if (!tpg->contrast_line[plane]) {
66 + goto free_contrast_line;
68 tpg->black_line[plane] =
69 vzalloc(array_size(pixelsz, max_w));
70 - if (!tpg->black_line[plane])
72 + if (!tpg->black_line[plane]) {
74 + goto free_contrast_line;
76 tpg->random_line[plane] =
77 vzalloc(array3_size(max_w, 2, pixelsz));
78 - if (!tpg->random_line[plane])
80 + if (!tpg->random_line[plane]) {
82 + goto free_contrast_line;
88 + for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
89 + vfree(tpg->contrast_line[plane]);
90 + vfree(tpg->black_line[plane]);
91 + vfree(tpg->random_line[plane]);
92 + tpg->contrast_line[plane] = NULL;
93 + tpg->black_line[plane] = NULL;
94 + tpg->random_line[plane] = NULL;
97 + for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
98 + for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
99 + vfree(tpg->lines[pat][plane]);
100 + tpg->lines[pat][plane] = NULL;
103 + vfree(tpg->downsampled_lines[pat][plane]);
104 + tpg->downsampled_lines[pat][plane] = NULL;
108 EXPORT_SYMBOL_GPL(tpg_alloc);