| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| Date: Fri, 12 May 2017 14:38:03 +0200 |
| Subject: drm/vc4: Fix resource leak in 'vc4_get_hang_state_ioctl()' in error handling path |
| |
| From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| |
| |
| [ Upstream commit d0b1d259a4b58b21a21ea82d7174bf7ea825e9cc ] |
| |
| If one 'drm_gem_handle_create()' fails, we leak somes handles and some |
| memory. |
| |
| In order to fix it: |
| - move the 'free(bo_state)' at the end of the function so that it is also |
| called in the eror handling path. This has the side effect to also try |
| to free it if the first 'kcalloc' fails. This is harmless. |
| - add a new label, err_delete_handle, in order to delete already |
| allocated handles in error handling path |
| - remove the now useless 'err' label |
| |
| The way the code is now written will also delete the handles if the |
| 'copy_to_user()' call fails. |
| |
| Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| Reviewed-by: Eric Anholt <eric@anholt.net> |
| Link: http://patchwork.freedesktop.org/patch/msgid/20170512123803.1886-1-christophe.jaillet@wanadoo.fr |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/vc4/vc4_gem.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/gpu/drm/vc4/vc4_gem.c |
| +++ b/drivers/gpu/drm/vc4/vc4_gem.c |
| @@ -110,8 +110,8 @@ vc4_get_hang_state_ioctl(struct drm_devi |
| &handle); |
| |
| if (ret) { |
| - state->bo_count = i - 1; |
| - goto err; |
| + state->bo_count = i; |
| + goto err_delete_handle; |
| } |
| bo_state[i].handle = handle; |
| bo_state[i].paddr = vc4_bo->base.paddr; |
| @@ -123,13 +123,16 @@ vc4_get_hang_state_ioctl(struct drm_devi |
| state->bo_count * sizeof(*bo_state))) |
| ret = -EFAULT; |
| |
| - kfree(bo_state); |
| +err_delete_handle: |
| + if (ret) { |
| + for (i = 0; i < state->bo_count; i++) |
| + drm_gem_handle_delete(file_priv, bo_state[i].handle); |
| + } |
| |
| err_free: |
| - |
| vc4_free_hang_state(dev, kernel_state); |
| + kfree(bo_state); |
| |
| -err: |
| return ret; |
| } |
| |