Handle result of kmalloc() to prevent possible NULL pointer dereference. For the sake of not introducing additional layer of indentation, extract seqno_waiter_rm_context creating code into a separate helper function.
Judging by commit 0039a3b35b10 ("drm/vmwgfx: Add seqno waiter for sync_files"), possible errors in seqno waiting aren't fatal, thus just skip this block if an allocation failure occurs - no need to propagate upwards.
Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool.
Fixes: 0039a3b35b10 ("drm/vmwgfx: Add seqno waiter for sync_files") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 27 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index e831e324e737..12d897eca410 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -4085,6 +4085,23 @@ static void seqno_waiter_rm_cb(struct dma_fence *f, struct dma_fence_cb *cb) kfree(ctx); }
+static void seqno_waiter_create(struct dma_fence *f, + struct vmw_private *dev_priv) +{ + struct seqno_waiter_rm_context *ctx; + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return; + + ctx->dev_priv = dev_priv; + vmw_seqno_waiter_add(dev_priv); + if (dma_fence_add_callback(f, &ctx->base, seqno_waiter_rm_cb) < 0) { + vmw_seqno_waiter_remove(dev_priv); + kfree(ctx); + } +} + int vmw_execbuf_process(struct drm_file *file_priv, struct vmw_private *dev_priv, void __user *user_commands, void *kernel_commands, @@ -4265,15 +4282,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, } else { /* Link the fence with the FD created earlier */ fd_install(out_fence_fd, sync_file->file); - struct seqno_waiter_rm_context *ctx = - kmalloc(sizeof(*ctx), GFP_KERNEL); - ctx->dev_priv = dev_priv; - vmw_seqno_waiter_add(dev_priv); - if (dma_fence_add_callback(&fence->base, &ctx->base, - seqno_waiter_rm_cb) < 0) { - vmw_seqno_waiter_remove(dev_priv); - kfree(ctx); - } + seqno_waiter_create(&fence->base, dev_priv); } }