From patchwork Wed Jun 14 23:18:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 9787755 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 EA591602CB for ; Thu, 15 Jun 2017 00:59:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFA8C284DC for ; Thu, 15 Jun 2017 00:59:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D43B8284ED; Thu, 15 Jun 2017 00:59:41 +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.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID 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 5DDDA284DC for ; Thu, 15 Jun 2017 00:59:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 14A306E68D; Thu, 15 Jun 2017 00:57:46 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf0-x243.google.com (mail-lf0-x243.google.com [IPv6:2a00:1450:4010:c07::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 593326E630 for ; Wed, 14 Jun 2017 23:18:59 +0000 (UTC) Received: by mail-lf0-x243.google.com with SMTP id x81so1602374lfb.3 for ; Wed, 14 Jun 2017 16:18:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=4APKdYhyev5SOxN9nydMHwtbrWPbJMp29Oesrn845sA=; b=qHolsGZCXxAtlEeshevPUZHWCqtgeun0bNYvBReZ3/ZbPtTPgF51gvixPtrqWWLiHO 98Qhgjwz5XFdYRTOCbjbfCyi1woZ2iWMaQisMGrQnUnHhQn2pMJ2zHBgMYuitxiTOaT5 epbgctNLF7zQ0uUNvH5Uzx2Hr5DlFIbhk6Kz7tllAXTHPGzB7EC6sOdvOWu9vdd9GlWR XoEbaIBw5OZpWoe1oA0+SUZWEouqx8m5333s0BHH4Mqzm9x9mFd+RrAOUnLBmqLXA8fV kj057R5fSf1XINr5tnZef1FfJL1bjzZAPHJOKsGcPFffRZy/9kOGAZ9S3Y41db5d386P WhFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=4APKdYhyev5SOxN9nydMHwtbrWPbJMp29Oesrn845sA=; b=UHxlEXtR9AsUvQ2CfEcRqORt+YqFblOVWXWmyNsRT3qH7LCT1hqUnW6tdM9QOl9dCg upLv1ogm2hiLkIlY+a8DKGQaqy8b1LdQENxaCnjT3cZLcnHEguudOEB0ZZKqMfC6c70h 5eW833GskW0ITADds41VSerVxYdYtzpIUSfTcywvk7Fn8ob8qVrnKNjYQ0W2VfXM4Ol9 2e9e4SiJAiNAiffh95dc4mBIZ71RTsKCIb4Z1GKChGOhIWHvpGDJsIWd6RUu4HD1yPH2 Dj25Oum8LItDe9z9wUjKjajYb+lKs0Yqeo/f7sszF+QGKFMZ7k/JmgLCWWeNx71JDRR3 gJXA== X-Gm-Message-State: AKS2vOwH+V149VrtGK2XD5Lfkd90IE6R8h08IfCPXz7I2OibBcO6D9HD yq9dhXbrF3vYaA== X-Received: by 10.25.15.157 with SMTP id 29mr679815lfp.10.1497482337725; Wed, 14 Jun 2017 16:18:57 -0700 (PDT) Received: from localhost.localdomain (ppp109-252-91-7.pppoe.spdop.ru. [109.252.91.7]) by smtp.gmail.com with ESMTPSA id i24sm290165ljb.63.2017.06.14.16.18.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Jun 2017 16:18:57 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Mikko Perttunen , Erik Faye-Lund Subject: [PATCH v3 03/20] drm/tegra: Check for malformed offsets and sizes in the 'submit' IOCTL Date: Thu, 15 Jun 2017 02:18:26 +0300 Message-Id: <57b9f4f8d6276170559dd06f6ae99d034de138e3.1497480755.git.digetx@gmail.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: References: In-Reply-To: References: X-Mailman-Approved-At: Thu, 15 Jun 2017 00:57:20 +0000 Cc: linux-tegra@vger.kernel.org, DRI Development 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 commands buffer claims a number of words that is higher than its BO can fit, a kernel OOPS will be fired on the out-of-bounds BO access. This was triggered by an opentegra Xorg driver that erroneously pushed too many commands to the pushbuf. The CDMA commands buffer address is 4 bytes aligned, so check its alignment. The maximum number of the CDMA gather fetches is 16383, add a check for it. Add a sanity check for the relocations in a same way. [ 46.829393] Unable to handle kernel paging request at virtual address f09b2000 ... [] (host1x_job_pin) from [] (tegra_drm_submit+0x474/0x510) [] (tegra_drm_submit) from [] (tegra_submit+0x50/0x6c) [] (tegra_submit) from [] (drm_ioctl+0x1e4/0x3ec) [] (drm_ioctl) from [] (do_vfs_ioctl+0x9c/0x8e4) [] (do_vfs_ioctl) from [] (SyS_ioctl+0x34/0x5c) [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) Signed-off-by: Dmitry Osipenko Reviewed-by: Erik Faye-Lund Reviewed-by: Mikko Perttunen --- drivers/gpu/drm/tegra/drm.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/gem.c | 5 ----- drivers/gpu/drm/tegra/gem.h | 5 +++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index f9282da94a1f..c9246405fc7b 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -26,6 +26,7 @@ #define DRIVER_PATCHLEVEL 0 #define CARVEOUT_SZ SZ_64M +#define CDMA_GATHER_FETCHES_MAX_NB 16383 struct tegra_drm_file { struct idr contexts; @@ -383,18 +384,42 @@ int tegra_drm_submit(struct tegra_drm_context *context, while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; + struct tegra_bo *obj; + u64 offset; if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) { err = -EFAULT; goto fail; } + /* + * The maximum number of CDMA gather fetches is 16383, a higher + * value means the words count is malformed. + */ + if (cmdbuf.words > CDMA_GATHER_FETCHES_MAX_NB) { + err = -EINVAL; + goto fail; + } + bo = host1x_bo_lookup(file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; } + offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32); + obj = host1x_to_tegra_bo(bo); + + /* + * Gather buffer base address must be 4-bytes aligned, + * unaligned offset is malformed and cause commands stream + * corruption on the buffer address relocation. + */ + if (offset & 3 || offset >= obj->gem.size) { + err = -EINVAL; + goto fail; + } + host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; @@ -402,11 +427,35 @@ int tegra_drm_submit(struct tegra_drm_context *context, /* copy and resolve relocations from submit */ while (num_relocs--) { + struct host1x_reloc *reloc; + struct tegra_bo *obj; + err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs], &relocs[num_relocs], drm, file); if (err < 0) goto fail; + + reloc = &job->relocarray[num_relocs]; + obj = host1x_to_tegra_bo(reloc->cmdbuf.bo); + + /* + * The unaligned cmdbuf offset will cause an unaligned write + * during of the relocations patching, corrupting the commands + * stream. + */ + if (reloc->cmdbuf.offset & 3 || + reloc->cmdbuf.offset >= obj->gem.size) { + err = -EINVAL; + goto fail; + } + + obj = host1x_to_tegra_bo(reloc->target.bo); + + if (reloc->target.offset >= obj->gem.size) { + err = -EINVAL; + goto fail; + } } if (copy_from_user(job->waitchk, waitchks, diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 424569b53e57..7a39a355678a 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -20,11 +20,6 @@ #include "drm.h" #include "gem.h" -static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) -{ - return container_of(bo, struct tegra_bo, base); -} - static void tegra_bo_put(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h index 6c5f12ac0087..8b32a6fd586d 100644 --- a/drivers/gpu/drm/tegra/gem.h +++ b/drivers/gpu/drm/tegra/gem.h @@ -52,6 +52,11 @@ static inline struct tegra_bo *to_tegra_bo(struct drm_gem_object *gem) return container_of(gem, struct tegra_bo, gem); } +static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) +{ + return container_of(bo, struct tegra_bo, base); +} + struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size, unsigned long flags); struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,