After a successful BALANCE/PARALLEL_SUBMIT extension on context
creation, error during processing of next user extension leaks
the siblings[] array. Fix that.

Discovered using AI-assisted static analysis confirmed by
Intel Product Security.

Reported-by: Martin Hodo <[email protected]>
Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create 
parameters (v5)")
Cc: Faith Ekstrand <[email protected]>
Cc: Simona Vetter <[email protected]>
Cc: Tvrtko Ursulin <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: <[email protected]> # v5.15+
Signed-off-by: Joonas Lahtinen <[email protected]>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 22 +++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index aeafe1742d30..87fce2adfeef 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -769,8 +769,8 @@ static int set_proto_ctx_engines(struct 
drm_i915_file_private *fpriv,
                struct intel_engine_cs *engine;
 
                if (copy_from_user(&ci, &user->engines[n], sizeof(ci))) {
-                       kfree(set.engines);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto err;
                }
 
                memset(&set.engines[n], 0, sizeof(set.engines[n]));
@@ -786,8 +786,8 @@ static int set_proto_ctx_engines(struct 
drm_i915_file_private *fpriv,
                        drm_dbg(&i915->drm,
                                "Invalid engine[%d]: { class:%d, instance:%d 
}\n",
                                n, ci.engine_class, ci.engine_instance);
-                       kfree(set.engines);
-                       return -ENOENT;
+                       err = -ENOENT;
+                       goto err;
                }
 
                set.engines[n].type = I915_GEM_ENGINE_TYPE_PHYSICAL;
@@ -800,15 +800,21 @@ static int set_proto_ctx_engines(struct 
drm_i915_file_private *fpriv,
                                           set_proto_ctx_engines_extensions,
                                           
ARRAY_SIZE(set_proto_ctx_engines_extensions),
                                           &set);
-       if (err) {
-               kfree(set.engines);
-               return err;
-       }
+       if (err)
+               goto err_extensions;
 
        pc->num_user_engines = set.num_engines;
        pc->user_engines = set.engines;
 
        return 0;
+
+err_extensions:
+       for (n = 0; n < set.num_engines; n++)
+               kfree(set.engines[n].siblings);
+err:
+       kfree(set.engines);
+
+       return err;
 }
 
 static int set_proto_ctx_sseu(struct drm_i915_file_private *fpriv,
-- 
2.54.0

Reply via email to