drm/amd/display: handle failed allocation during stream construction
authorJosip Pavic <Josip.Pavic@amd.com>
Mon, 6 Jul 2020 19:43:39 +0000 (15:43 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 14 Jul 2020 18:37:59 +0000 (14:37 -0400)
[Why]
Failing to allocate a transfer function during stream construction leads
to a null pointer dereference

[How]
Handle the failed allocation by failing the stream construction

Cc: stable@vger.kernel.org
Signed-off-by: Josip Pavic <Josip.Pavic@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_stream.c

index 3b89737..d6989d1 100644 (file)
@@ -56,7 +56,7 @@ void update_stream_signal(struct dc_stream_state *stream, struct dc_sink *sink)
        }
 }
 
-static void dc_stream_construct(struct dc_stream_state *stream,
+static bool dc_stream_construct(struct dc_stream_state *stream,
        struct dc_sink *dc_sink_data)
 {
        uint32_t i = 0;
@@ -118,11 +118,17 @@ static void dc_stream_construct(struct dc_stream_state *stream,
        update_stream_signal(stream, dc_sink_data);
 
        stream->out_transfer_func = dc_create_transfer_func();
+       if (stream->out_transfer_func == NULL) {
+               dc_sink_release(dc_sink_data);
+               return false;
+       }
        stream->out_transfer_func->type = TF_TYPE_BYPASS;
        stream->out_transfer_func->ctx = stream->ctx;
 
        stream->stream_id = stream->ctx->dc_stream_id_count;
        stream->ctx->dc_stream_id_count++;
+
+       return true;
 }
 
 static void dc_stream_destruct(struct dc_stream_state *stream)
@@ -164,13 +170,20 @@ struct dc_stream_state *dc_create_stream_for_sink(
 
        stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL);
        if (stream == NULL)
-               return NULL;
+               goto alloc_fail;
 
-       dc_stream_construct(stream, sink);
+       if (dc_stream_construct(stream, sink) == false)
+               goto construct_fail;
 
        kref_init(&stream->refcount);
 
        return stream;
+
+construct_fail:
+       kfree(stream);
+
+alloc_fail:
+       return NULL;
 }
 
 struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)