| From e14fa79c4122f55bf63e05ac007e4889d2c70e60 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 21 Jan 2022 11:26:13 +0000 |
| Subject: drm/amd/display: Fix memory leak |
| |
| From: Yongzhi Liu <lyz_cs@pku.edu.cn> |
| |
| [ Upstream commit 5d5c6dba2b43e28845d7d7ed32a36802329a5f52 ] |
| |
| [why] |
| Resource release is needed on the error handling path |
| to prevent memory leak. |
| |
| [how] |
| Fix this by adding kfree on the error handling path. |
| |
| Reviewed-by: Harry Wentland <harry.wentland@amd.com> |
| Signed-off-by: Yongzhi Liu <lyz_cs@pku.edu.cn> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 80 ++++++++++++++----- |
| 1 file changed, 60 insertions(+), 20 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
| index f4e829ec8e10..ab58bcb11677 100644 |
| --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
| +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
| @@ -227,8 +227,10 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -389,8 +391,10 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user((*(rd_buf + result)), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -1317,8 +1321,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -1334,8 +1340,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -1504,8 +1512,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -1521,8 +1531,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -1689,8 +1701,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -1706,8 +1720,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -1870,8 +1886,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -1887,8 +1905,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -2046,8 +2066,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -2063,8 +2085,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -2103,8 +2127,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -2120,8 +2146,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -2175,8 +2203,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -2192,8 +2222,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -2247,8 +2279,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, |
| break; |
| } |
| |
| - if (!pipe_ctx) |
| + if (!pipe_ctx) { |
| + kfree(rd_buf); |
| return -ENXIO; |
| + } |
| |
| dsc = pipe_ctx->stream_res.dsc; |
| if (dsc) |
| @@ -2264,8 +2298,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, |
| break; |
| |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| |
| buf += 1; |
| size -= 1; |
| @@ -3255,8 +3291,10 @@ static ssize_t dcc_en_bits_read( |
| dc->hwss.get_dcc_en_bits(dc, dcc_en_bits); |
| |
| rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); |
| - if (!rd_buf) |
| + if (!rd_buf) { |
| + kfree(dcc_en_bits); |
| return -ENOMEM; |
| + } |
| |
| for (i = 0; i < num_pipes; i++) |
| offset += snprintf(rd_buf + offset, rd_buf_size - offset, |
| @@ -3269,8 +3307,10 @@ static ssize_t dcc_en_bits_read( |
| if (*pos >= rd_buf_size) |
| break; |
| r = put_user(*(rd_buf + result), buf); |
| - if (r) |
| + if (r) { |
| + kfree(rd_buf); |
| return r; /* r = -EFAULT */ |
| + } |
| buf += 1; |
| size -= 1; |
| *pos += 1; |
| -- |
| 2.35.1 |
| |