From patchwork Tue Aug 13 19:38:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 2843983 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3B0A6BF546 for ; Tue, 13 Aug 2013 19:53:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3BA75204D2 for ; Tue, 13 Aug 2013 19:53:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 49C5120495 for ; Tue, 13 Aug 2013 19:53:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 40D1BE7C73 for ; Tue, 13 Aug 2013 12:53:22 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ee0-f47.google.com (mail-ee0-f47.google.com [74.125.83.47]) by gabe.freedesktop.org (Postfix) with ESMTP id CF020E7C6C for ; Tue, 13 Aug 2013 12:40:09 -0700 (PDT) Received: by mail-ee0-f47.google.com with SMTP id d49so4364538eek.20 for ; Tue, 13 Aug 2013 12:40:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lfSs30G3I4yYXE6XHf8dOzJkJvd6xVpzsQ3F0XmchoM=; b=w8VQzTvIubcCz5dABGEkmlqqlOxdS6LByvxdg1A2FhlqsxFYgM+M21VtVTRLG+1sLh zWC8U+1evJHuQXybqR9FBo/ccpP2NNxMZelf5wJztA+tANKBtkCdKZsHBaKhm/xZb56B VbI/yXwhCZAa9mzEEDZthks7QYHyGcqPaaP3jAtWCzCFP32ui96xlYUiT72CPbiVYiKN ZoGx5Da/W09loo53XMwiLd2DmeXEGWMu54Bb1UWwObhZwdCuIUR/B8+G5h1kfINPBEGr BdffYyyDDYi4giY8fWd7LQykK2Ub+5O2+3c1IHAF4oVXy0+GvU3vGkJ1IpHMx6hquGV4 xCBg== X-Received: by 10.15.41.77 with SMTP id r53mr4936877eev.64.1376422809034; Tue, 13 Aug 2013 12:40:09 -0700 (PDT) Received: from localhost.localdomain (stgt-5f71b8eb.pool.mediaWays.net. [95.113.184.235]) by mx.google.com with ESMTPSA id a1sm68812938eem.1.2013.08.13.12.40.07 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 13 Aug 2013 12:40:08 -0700 (PDT) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [PATCH 10/16] drm/gem: implement mmap access management Date: Tue, 13 Aug 2013 21:38:31 +0200 Message-Id: <1376422717-12229-11-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1376422717-12229-1-git-send-email-dh.herrmann@gmail.com> References: <1376422717-12229-1-git-send-email-dh.herrmann@gmail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Implement automatic access management for mmap offsets for all GEM drivers. This prevents user-space applications from "guessing" GEM BO offsets and accessing buffers which they don't own. TTM drivers or other modesetting drivers with custom mm handling might make use of GEM but don't need its mmap helpers. To avoid unnecessary overhead, we limit GEM access management to drivers using DRIVER_GEM_MMAP. So for TTM drivers GEM will not call any *_allow() or *_revoke() helpers. Signed-off-by: David Herrmann --- Documentation/DocBook/drm.tmpl | 13 +++++++++++++ drivers/gpu/drm/drm_gem.c | 36 ++++++++++++++++++++++++++++++++---- include/drm/drmP.h | 1 + 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 87e22ec..a388749 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -223,6 +223,19 @@ + DRIVER_GEM_MMAP + + Driver uses default GEM mmap helpers. This flag guarantees that + GEM core takes care of buffer access management and prevents + unprivileged users from mapping random buffers. This flag should + only be set by GEM-only drivers that use the drm_gem_mmap_*() + helpers directly. TTM, on the other hand, takes care of access + management itself, even though drivers might use DRIVER_GEM and + TTM at the same time. See the DRM VMA Offset Manager interface for + more information on buffer mmap() access management. + + + DRIVER_MODESET Driver supports mode setting interfaces (KMS). diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 7043d89..887274f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -236,6 +236,9 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) drm_gem_remove_prime_handles(obj, filp); + if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) + drm_vma_node_revoke(&obj->vma_node, filp->filp); + if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, filp); drm_gem_object_handle_unreference_unlocked(obj); @@ -288,15 +291,26 @@ drm_gem_handle_create(struct drm_file *file_priv, drm_gem_object_handle_reference(obj); + if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) { + ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp); + if (ret) + goto err_handle; + } + if (dev->driver->gem_open_object) { ret = dev->driver->gem_open_object(obj, file_priv); - if (ret) { - drm_gem_handle_delete(file_priv, *handlep); - return ret; - } + if (ret) + goto err_node; } return 0; + +err_node: + if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) + drm_vma_node_revoke(&obj->vma_node, file_priv->filp); +err_handle: + drm_gem_handle_delete(file_priv, *handlep); + return ret; } EXPORT_SYMBOL(drm_gem_handle_create); @@ -486,6 +500,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) drm_gem_remove_prime_handles(obj, file_priv); + if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) + drm_vma_node_revoke(&obj->vma_node, file_priv->filp); + if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); @@ -610,6 +627,10 @@ EXPORT_SYMBOL(drm_gem_vm_close); * the GEM object is not looked up based on its fake offset. To implement the * DRM mmap operation, drivers should use the drm_gem_mmap() function. * + * drm_gem_mmap_obj() assumes the user is granted access to the buffer while + * drm_gem_mmap() prevents unprivileged users from mapping random objects. So + * callers must verify access restrictions before calling this helper. + * * NOTE: This function has to be protected with dev->struct_mutex * * Return 0 or success or -EINVAL if the object size is smaller than the VMA @@ -658,6 +679,9 @@ EXPORT_SYMBOL(drm_gem_mmap_obj); * Look up the GEM object based on the offset passed in (vma->vm_pgoff will * contain the fake offset we created when the GTT map ioctl was called on * the object) and map it with a call to drm_gem_mmap_obj(). + * + * If the caller is not granted access to the buffer object, the mmap will fail + * with EACCES. Please see DRIVER_GEM_MMAP for more information. */ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) { @@ -678,6 +702,10 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) if (!node) { mutex_unlock(&dev->struct_mutex); return drm_mmap(filp, vma); + } else if (drm_core_check_feature(dev, DRIVER_GEM_MMAP) && + !drm_vma_node_is_allowed(node, filp)) { + mutex_unlock(&dev->struct_mutex); + return -EACCES; } obj = container_of(node, struct drm_gem_object, vma_node); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3ecdde6..d51accd 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -152,6 +152,7 @@ int drm_err(const char *func, const char *format, ...); #define DRIVER_GEM 0x1000 #define DRIVER_MODESET 0x2000 #define DRIVER_PRIME 0x4000 +#define DRIVER_GEM_MMAP 0x8000 #define DRIVER_BUS_PCI 0x1 #define DRIVER_BUS_PLATFORM 0x2