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 <[email protected]>
---
 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

Reply via email to