From patchwork Sun May 14 20:47:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 9725939 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 EDEA460381 for ; Mon, 15 May 2017 00:49:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E012E2891E for ; Mon, 15 May 2017 00:49:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D4C8128935; Mon, 15 May 2017 00:49: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.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 793A62891E for ; Mon, 15 May 2017 00:49:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 536A289DC7; Mon, 15 May 2017 00:48:39 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr0-x242.google.com (mail-wr0-x242.google.com [IPv6:2a00:1450:400c:c0c::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8D9F56E032 for ; Sun, 14 May 2017 20:48:54 +0000 (UTC) Received: by mail-wr0-x242.google.com with SMTP id w50so12677568wrc.0 for ; Sun, 14 May 2017 13:48:54 -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; bh=sBUY7zgADd08L8nZW8F8bCCtYzkR94rxzGxj69kxLts=; b=C/tE4kljBT4KBT4yNr6mBtG8xrxZ7d+jl1dAIR9EeQ+L2CF5ymrKdSusS63G5IZfA0 py7wDhvUSCLooiOnhLz17lw5aa6cMayxSOJq80ioWRIF06QBCyFvJaz/mrpCfp6zsoWr /Uocw9vbqCqtNbt1HmQY8Nse5p9j/i8cgQJ/qAUIrsNxkT4qrEIy9stEYS1QzbFyORpq uOqgOqCespo0XUoZw7v4AcIeVaDz4wciknzQW8e/LPC3/BCEAf/K6AMMm/aWlYAIkH/O VA5eP7moYIvvGRR2mFgeqETUms/BsycrAz/e/G2AQKBSOCEgTrDaD/vVkb6U32716fMf 0SYA== 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; bh=sBUY7zgADd08L8nZW8F8bCCtYzkR94rxzGxj69kxLts=; b=obrvPPooM7O0P4wWzhU+oqtmHkkxSXrHygD816BzUj+lqtkdDKjyOcj/FFLa8G9KVe dhJOag9EIf8icWb1COR6A5wlX4+z2w6yZvF3tZZr5zHnUIJ64C5BEqj+MgVbPqMES604 30TS+8nSy4ojno9N28QHB4TwmOiYjsvi/FQ7B2jCe296T14Te/ML0Ukjy4WB8DA8B+5q T/zltsYdl5yTXQfbB0tXPA0dJrDm66YK/kQhGRdADt1K77B2Qc26+fJ8smQnxAjf8V3c xyqHzEBaVLyvp4YDr3VG6RxYNcUBlCQZd7PTkFLaTKNlyyzWvPrlFVRjDB+m6JU5wnuu urzA== X-Gm-Message-State: AODbwcDlsq+dWAjSG5YFQM0WK28hXJ8S753KSO8hQPNgfvHeDnd2vv3r VnZAduSJaXpHJl220Yk= X-Received: by 10.46.21.28 with SMTP id s28mr1145629ljd.112.1494794933183; Sun, 14 May 2017 13:48:53 -0700 (PDT) Received: from localhost.localdomain (ppp109-252-91-175.pppoe.spdop.ru. [109.252.91.175]) by smtp.gmail.com with ESMTPSA id 75sm1839959lja.53.2017.05.14.13.48.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 14 May 2017 13:48:52 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding , Mikko Perttunen Subject: [PATCH] drm/tegra: Check offsets of a submitted command buffer and of relocations Date: Sun, 14 May 2017 23:47:33 +0300 Message-Id: <20170514204734.22130-3-digetx@gmail.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170514204734.22130-1-digetx@gmail.com> References: <20170514204734.22130-1-digetx@gmail.com> X-Mailman-Approved-At: Mon, 15 May 2017 00:48:34 +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 CMDA commands buffer address is 4 bytes aligned, so check the alignment as well. 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 --- drivers/gpu/drm/tegra/drm.c | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/gem.c | 5 ----- drivers/gpu/drm/tegra/gem.h | 5 +++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 768750226452..c5844a065681 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -362,6 +362,8 @@ 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; @@ -374,6 +376,14 @@ int tegra_drm_submit(struct tegra_drm_context *context, goto fail; } + offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32); + obj = host1x_to_tegra_bo(bo); + + if (offset & 3 || offset > obj->gem.size) { + err = -EINVAL; + goto fail; + } + host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; @@ -381,11 +391,31 @@ 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); + + 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 & 3 || + 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 b76d7ac75696..a0ff30c01ac1 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,