aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe JAILLET <christophe.jaillet@wanadoo.fr>2017-05-12 08:38:03 -0400
committerEric Anholt <eric@anholt.net>2017-06-12 20:11:39 -0400
commitd0b1d259a4b58b21a21ea82d7174bf7ea825e9cc (patch)
tree478890f4ecd797fd31e89b1e8b7b66e00f3f5801
parent24bb206f32cdaa76c59444b62be51708dc16fbe8 (diff)
drm/vc4: Fix resource leak in 'vc4_get_hang_state_ioctl()' in error handling path
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
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 9dc7646d49ed..d5b821ad06af 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -111,8 +111,8 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
111 &handle); 111 &handle);
112 112
113 if (ret) { 113 if (ret) {
114 state->bo_count = i - 1; 114 state->bo_count = i;
115 goto err; 115 goto err_delete_handle;
116 } 116 }
117 bo_state[i].handle = handle; 117 bo_state[i].handle = handle;
118 bo_state[i].paddr = vc4_bo->base.paddr; 118 bo_state[i].paddr = vc4_bo->base.paddr;
@@ -124,13 +124,16 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
124 state->bo_count * sizeof(*bo_state))) 124 state->bo_count * sizeof(*bo_state)))
125 ret = -EFAULT; 125 ret = -EFAULT;
126 126
127 kfree(bo_state); 127err_delete_handle:
128 if (ret) {
129 for (i = 0; i < state->bo_count; i++)
130 drm_gem_handle_delete(file_priv, bo_state[i].handle);
131 }
128 132
129err_free: 133err_free:
130
131 vc4_free_hang_state(dev, kernel_state); 134 vc4_free_hang_state(dev, kernel_state);
135 kfree(bo_state);
132 136
133err:
134 return ret; 137 return ret;
135} 138}
136 139