From patchwork Fri Jan 20 16:02:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Jakobi X-Patchwork-Id: 9528885 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 D2B0B601B7 for ; Fri, 20 Jan 2017 16:03:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB90328688 for ; Fri, 20 Jan 2017 16:03:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C05D6286B0; Fri, 20 Jan 2017 16:03:14 +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, 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 269B828688 for ; Fri, 20 Jan 2017 16:03:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0062B6EBF5; Fri, 20 Jan 2017 16:03:13 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.math.uni-bielefeld.de (smtp.math.uni-bielefeld.de [129.70.45.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id F13DA6E1C0 for ; Fri, 20 Jan 2017 16:03:09 +0000 (UTC) Received: from chidori.dhcp.uni-bielefeld.de (dhcp-10-68-171-17.dhcp.uni-bielefeld.de [10.68.171.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client did not present a certificate) by smtp.math.uni-bielefeld.de (Postfix) with ESMTPSA id 3EDD05FAF8; Fri, 20 Jan 2017 17:03:08 +0100 (CET) From: Tobias Jakobi To: linux-samsung-soc@vger.kernel.org Subject: [PATCH 3/3] drm/exynos: g2d: prevent integer overflow in set_cmdlist() ioctl Date: Fri, 20 Jan 2017 17:02:52 +0100 Message-Id: <1484928172-16784-3-git-send-email-tjakobi@math.uni-bielefeld.de> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1484928172-16784-1-git-send-email-tjakobi@math.uni-bielefeld.de> References: <1484928172-16784-1-git-send-email-tjakobi@math.uni-bielefeld.de> Cc: Tobias Jakobi , 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 From: Joonyoung Shim The size computations done in the ioctl function use an integer. If userspace submits a request with req->cmd_nr or req->cmd_buf_nr set to INT_MAX, the integer computations overflow later, leading to potential (kernel) memory corruption. Prevent this issue by enforcing a limit on the number of submitted commands, so that we have enough headroom later for the size computations. Note that this change has no impact on the currently available users in userspace, like e.g. libdrm/exynos. While at it, also make a comment about the size computation more detailed. Signed-off-by: Joonyoung Shim Signed-off-by: Tobias Jakobi --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 6962f6b1..f8737d43 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -1193,6 +1193,16 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, if (!node) return -ENOMEM; + /* + * To avoid an integer overflow for the later size computations, we + * enforce a maximum number of submitted commands here. This limit is + * sufficient for all conceivable usage cases of the G2D. + */ + if (req->cmd_nr > G2D_CMDLIST_DATA_NUM || req->cmd_buf_nr > G2D_CMDLIST_DATA_NUM) { + dev_err(dev, "number of submitted G2D commands exceeds limit\n"); + return -EINVAL; + } + node->event = NULL; if (req->event_type != G2D_EVENT_NOT) { @@ -1250,7 +1260,11 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF; } - /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ + /* + * Check the size of cmdlist. The 2 that is added last comes from + * the implicit G2D_BITBLT_START that is appended once we have + * checked all the submitted commands. + */ size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2; if (size > G2D_CMDLIST_DATA_NUM) { dev_err(dev, "cmdlist size is too big\n");