In i915_gem_do_execbuffer(), add_fence_array() allocates and populates
eb.fences. Immediately after this, if both IN_FENCES flags are set, the
function returns -EINVAL directly without calling put_fence_array(),
resulting in a memory leak of the allocated fence array.
Fix this by jumping to err_ext in the error path, ensuring that
put_fence_array() is properly called to release the fence array.
Compile tested only. Issue found using a prototype static analysis tool
and code review.
Fixes: 13149e8bafc4 ("drm/i915: add syncobj timeline support")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
---
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index d49e96f9be51..43f267f98ba0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -3407,8 +3407,10 @@ i915_gem_do_execbuffer(struct drm_device *dev,
#define IN_FENCES (I915_EXEC_FENCE_IN | I915_EXEC_FENCE_SUBMIT)
if (args->flags & IN_FENCES) {
- if ((args->flags & IN_FENCES) == IN_FENCES)
- return -EINVAL;
+ if ((args->flags & IN_FENCES) == IN_FENCES) {
+ err = -EINVAL;
+ goto err_ext;
+ }
in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2));
if (!in_fence) {
--
2.34.1