From patchwork Fri May 12 12:38:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe JAILLET X-Patchwork-Id: 9724843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 90B0F600CB for ; Fri, 12 May 2017 19:35:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8639E2888A for ; Fri, 12 May 2017 19:35:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7AE202888D; Fri, 12 May 2017 19:35:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CAE5A2888A for ; Fri, 12 May 2017 19:35:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7AE576E73E; Fri, 12 May 2017 19:35:01 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.smtpout.orange.fr (smtp05.smtpout.orange.fr [80.12.242.127]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4603B6E0DF for ; Fri, 12 May 2017 12:38:16 +0000 (UTC) Received: from localhost.localdomain ([92.140.167.29]) by mwinf5d28 with ME id KQeA1v0180ePKv803QeBR9; Fri, 12 May 2017 14:38:13 +0200 X-ME-Helo: localhost.localdomain X-ME-Auth: Y2hyaXN0b3BoZS5qYWlsbGV0QHdhbmFkb28uZnI= X-ME-Date: Fri, 12 May 2017 14:38:13 +0200 X-ME-IP: 92.140.167.29 From: Christophe JAILLET To: eric@anholt.net, airlied@linux.ie Subject: [PATCH v2] drm/vc4: Fix resource leak in 'vc4_get_hang_state_ioctl()' in error handling path Date: Fri, 12 May 2017 14:38:03 +0200 Message-Id: <20170512123803.1886-1-christophe.jaillet@wanadoo.fr> X-Mailer: git-send-email 2.11.0 X-Mailman-Approved-At: Fri, 12 May 2017 19:34:31 +0000 Cc: Christophe JAILLET , kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP If one 'drm_gem_handle_create()' fails, we leak somes handles and some memory. In order to fix it: - move the 'free(bo_state)' at the end of the function so that it is also called in the eror handling path. This has the side effect to also try to free it if the first 'kcalloc' fails. This is harmless. - add a new label, err_delete_handle, in order to delete already allocated handles in error handling path - remove the now useless 'err' label The way the code is now written will also delete the handles if the 'copy_to_user()' call fails. Signed-off-by: Christophe JAILLET --- v2: reorder code and add a 'err_delete_handle' label in order to free resources in the correct order and avoid NULL pointer dereference --- drivers/gpu/drm/vc4/vc4_gem.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index e9c381c42139..891c7a22cf81 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -111,8 +111,8 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, &handle); if (ret) { - state->bo_count = i - 1; - goto err; + state->bo_count = i; + goto err_delete_handle; } bo_state[i].handle = handle; bo_state[i].paddr = vc4_bo->base.paddr; @@ -124,13 +124,16 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, state->bo_count * sizeof(*bo_state))) ret = -EFAULT; - kfree(bo_state); +err_delete_handle: + if (ret) { + for (i = 0; i < state->bo_count; i++) + drm_gem_handle_delete(file_priv, bo_state[i].handle); + } err_free: - vc4_free_hang_state(dev, kernel_state); + kfree(bo_state); -err: return ret; }